{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Convert TFLite model to PyTorch\n",
    "\n",
    "This uses the model **face_detection_front.tflite** from [MediaPipe](https://github.com/google/mediapipe/tree/master/mediapipe/models).\n",
    "\n",
    "Using conda environnement:\n",
    "```\n",
    "conda create -c pytorch -c conda-forge -n BlazeConv 'pytorch=1.6' jupyter opencv matplotlib\n",
    "```\n",
    "```\n",
    "conda activate BlazeConv\n",
    "```\n",
    "```\n",
    "pip install tflite\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Convert front camera TFLite model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import numpy as np\n",
    "from collections import OrderedDict"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Get the weights from the TFLite file"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Load the TFLite model using the FlatBuffers library:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "--2021-02-09 23:17:46--  https://github.com/google/mediapipe/raw/master/mediapipe/models/face_detection_front.tflite\n",
      "Résolution de github.com (github.com)… 140.82.121.3\n",
      "Connexion à github.com (github.com)|140.82.121.3|:443… connecté.\n",
      "requête HTTP transmise, en attente de la réponse… 302 Found\n",
      "Emplacement : https://raw.githubusercontent.com/google/mediapipe/master/mediapipe/models/face_detection_front.tflite [suivant]\n",
      "--2021-02-09 23:17:46--  https://raw.githubusercontent.com/google/mediapipe/master/mediapipe/models/face_detection_front.tflite\n",
      "Résolution de raw.githubusercontent.com (raw.githubusercontent.com)… 151.101.120.133\n",
      "Connexion à raw.githubusercontent.com (raw.githubusercontent.com)|151.101.120.133|:443… connecté.\n",
      "requête HTTP transmise, en attente de la réponse… 200 OK\n",
      "Taille : 229032 (224K) [application/octet-stream]\n",
      "Enregistre : «face_detection_front.tflite»\n",
      "\n",
      "face_detection_fron 100%[===================>] 223,66K  --.-KB/s    ds 0,01s   \n",
      "\n",
      "En-tête de dernière modification manquant — horodatage arrêté.\n",
      "2021-02-09 23:17:46 (18,7 MB/s) - «face_detection_front.tflite» enregistré [229032/229032]\n",
      "\n"
     ]
    }
   ],
   "source": [
    "!wget -N https://github.com/google/mediapipe/raw/master/mediapipe/models/face_detection_front.tflite"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "from tflite import Model\n",
    "\n",
    "front_data = open(\"./face_detection_front.tflite\", \"rb\").read()\n",
    "front_model = Model.GetRootAsModel(front_data, 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "b'keras2tflite_facedetector-front.tflite.generated'"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "front_subgraph = front_model.Subgraphs(0)\n",
    "front_subgraph.Name()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_shape(tensor):\n",
    "    return [tensor.Shape(i) for i in range(tensor.ShapeLength())]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "List all the tensors in the graph:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  0                       b'input' 0  0 [1, 128, 128, 3]\n",
      "  1               b'conv2d/Kernel' 1  1 [24, 5, 5, 3]\n",
      "  2                 b'conv2d/Bias' 1  2 [24]\n",
      "  3                      b'conv2d' 0  0 [1, 64, 64, 24]\n",
      "  4                  b'activation' 0  0 [1, 64, 64, 24]\n",
      "  5     b'depthwise_conv2d/Kernel' 1  3 [1, 3, 3, 24]\n",
      "  6       b'depthwise_conv2d/Bias' 1  4 [24]\n",
      "  7            b'depthwise_conv2d' 0  0 [1, 64, 64, 24]\n",
      "  8             b'conv2d_1/Kernel' 1  5 [24, 1, 1, 24]\n",
      "  9               b'conv2d_1/Bias' 1  6 [24]\n",
      " 10                    b'conv2d_1' 0  0 [1, 64, 64, 24]\n",
      " 11         b'add__xeno_compat__1' 0  0 [1, 64, 64, 24]\n",
      " 12                b'activation_1' 0  0 [1, 64, 64, 24]\n",
      " 13   b'depthwise_conv2d_1/Kernel' 1  7 [1, 3, 3, 24]\n",
      " 14     b'depthwise_conv2d_1/Bias' 1  8 [24]\n",
      " 15          b'depthwise_conv2d_1' 0  0 [1, 64, 64, 24]\n",
      " 16             b'conv2d_2/Kernel' 1  9 [28, 1, 1, 24]\n",
      " 17               b'conv2d_2/Bias' 1 10 [28]\n",
      " 18                    b'conv2d_2' 0  0 [1, 64, 64, 28]\n",
      " 19    b'channel_padding/Paddings' 2 11 [4, 2]\n",
      " 20             b'channel_padding' 0  0 [1, 64, 64, 28]\n",
      " 21       b'add_1__xeno_compat__1' 0  0 [1, 64, 64, 28]\n",
      " 22                b'activation_2' 0  0 [1, 64, 64, 28]\n",
      " 23   b'depthwise_conv2d_2/Kernel' 1 12 [1, 3, 3, 28]\n",
      " 24     b'depthwise_conv2d_2/Bias' 1 13 [28]\n",
      " 25          b'depthwise_conv2d_2' 0  0 [1, 32, 32, 28]\n",
      " 26               b'max_pooling2d' 0  0 [1, 32, 32, 28]\n",
      " 27             b'conv2d_3/Kernel' 1 14 [32, 1, 1, 28]\n",
      " 28               b'conv2d_3/Bias' 1 15 [32]\n",
      " 29                    b'conv2d_3' 0  0 [1, 32, 32, 32]\n",
      " 30  b'channel_padding_1/Paddings' 2 16 [4, 2]\n",
      " 31           b'channel_padding_1' 0  0 [1, 32, 32, 32]\n",
      " 32       b'add_2__xeno_compat__1' 0  0 [1, 32, 32, 32]\n",
      " 33                b'activation_3' 0  0 [1, 32, 32, 32]\n",
      " 34   b'depthwise_conv2d_3/Kernel' 1 17 [1, 3, 3, 32]\n",
      " 35     b'depthwise_conv2d_3/Bias' 1 18 [32]\n",
      " 36          b'depthwise_conv2d_3' 0  0 [1, 32, 32, 32]\n",
      " 37             b'conv2d_4/Kernel' 1 19 [36, 1, 1, 32]\n",
      " 38               b'conv2d_4/Bias' 1 20 [36]\n",
      " 39                    b'conv2d_4' 0  0 [1, 32, 32, 36]\n",
      " 40  b'channel_padding_2/Paddings' 2 21 [4, 2]\n",
      " 41           b'channel_padding_2' 0  0 [1, 32, 32, 36]\n",
      " 42       b'add_3__xeno_compat__1' 0  0 [1, 32, 32, 36]\n",
      " 43                b'activation_4' 0  0 [1, 32, 32, 36]\n",
      " 44   b'depthwise_conv2d_4/Kernel' 1 22 [1, 3, 3, 36]\n",
      " 45     b'depthwise_conv2d_4/Bias' 1 23 [36]\n",
      " 46          b'depthwise_conv2d_4' 0  0 [1, 32, 32, 36]\n",
      " 47             b'conv2d_5/Kernel' 1 24 [42, 1, 1, 36]\n",
      " 48               b'conv2d_5/Bias' 1 25 [42]\n",
      " 49                    b'conv2d_5' 0  0 [1, 32, 32, 42]\n",
      " 50  b'channel_padding_3/Paddings' 2 26 [4, 2]\n",
      " 51           b'channel_padding_3' 0  0 [1, 32, 32, 42]\n",
      " 52       b'add_4__xeno_compat__1' 0  0 [1, 32, 32, 42]\n",
      " 53                b'activation_5' 0  0 [1, 32, 32, 42]\n",
      " 54   b'depthwise_conv2d_5/Kernel' 1 27 [1, 3, 3, 42]\n",
      " 55     b'depthwise_conv2d_5/Bias' 1 28 [42]\n",
      " 56          b'depthwise_conv2d_5' 0  0 [1, 16, 16, 42]\n",
      " 57             b'max_pooling2d_1' 0  0 [1, 16, 16, 42]\n",
      " 58             b'conv2d_6/Kernel' 1 29 [48, 1, 1, 42]\n",
      " 59               b'conv2d_6/Bias' 1 30 [48]\n",
      " 60                    b'conv2d_6' 0  0 [1, 16, 16, 48]\n",
      " 61  b'channel_padding_4/Paddings' 2 31 [4, 2]\n",
      " 62           b'channel_padding_4' 0  0 [1, 16, 16, 48]\n",
      " 63       b'add_5__xeno_compat__1' 0  0 [1, 16, 16, 48]\n",
      " 64                b'activation_6' 0  0 [1, 16, 16, 48]\n",
      " 65   b'depthwise_conv2d_6/Kernel' 1 32 [1, 3, 3, 48]\n",
      " 66     b'depthwise_conv2d_6/Bias' 1 33 [48]\n",
      " 67          b'depthwise_conv2d_6' 0  0 [1, 16, 16, 48]\n",
      " 68             b'conv2d_7/Kernel' 1 34 [56, 1, 1, 48]\n",
      " 69               b'conv2d_7/Bias' 1 35 [56]\n",
      " 70                    b'conv2d_7' 0  0 [1, 16, 16, 56]\n",
      " 71  b'channel_padding_5/Paddings' 2 36 [4, 2]\n",
      " 72           b'channel_padding_5' 0  0 [1, 16, 16, 56]\n",
      " 73       b'add_6__xeno_compat__1' 0  0 [1, 16, 16, 56]\n",
      " 74                b'activation_7' 0  0 [1, 16, 16, 56]\n",
      " 75   b'depthwise_conv2d_7/Kernel' 1 37 [1, 3, 3, 56]\n",
      " 76     b'depthwise_conv2d_7/Bias' 1 38 [56]\n",
      " 77          b'depthwise_conv2d_7' 0  0 [1, 16, 16, 56]\n",
      " 78             b'conv2d_8/Kernel' 1 39 [64, 1, 1, 56]\n",
      " 79               b'conv2d_8/Bias' 1 40 [64]\n",
      " 80                    b'conv2d_8' 0  0 [1, 16, 16, 64]\n",
      " 81  b'channel_padding_6/Paddings' 2 41 [4, 2]\n",
      " 82           b'channel_padding_6' 0  0 [1, 16, 16, 64]\n",
      " 83       b'add_7__xeno_compat__1' 0  0 [1, 16, 16, 64]\n",
      " 84                b'activation_8' 0  0 [1, 16, 16, 64]\n",
      " 85   b'depthwise_conv2d_8/Kernel' 1 42 [1, 3, 3, 64]\n",
      " 86     b'depthwise_conv2d_8/Bias' 1 43 [64]\n",
      " 87          b'depthwise_conv2d_8' 0  0 [1, 16, 16, 64]\n",
      " 88             b'conv2d_9/Kernel' 1 44 [72, 1, 1, 64]\n",
      " 89               b'conv2d_9/Bias' 1 45 [72]\n",
      " 90                    b'conv2d_9' 0  0 [1, 16, 16, 72]\n",
      " 91  b'channel_padding_7/Paddings' 2 46 [4, 2]\n",
      " 92           b'channel_padding_7' 0  0 [1, 16, 16, 72]\n",
      " 93       b'add_8__xeno_compat__1' 0  0 [1, 16, 16, 72]\n",
      " 94                b'activation_9' 0  0 [1, 16, 16, 72]\n",
      " 95   b'depthwise_conv2d_9/Kernel' 1 47 [1, 3, 3, 72]\n",
      " 96     b'depthwise_conv2d_9/Bias' 1 48 [72]\n",
      " 97          b'depthwise_conv2d_9' 0  0 [1, 16, 16, 72]\n",
      " 98            b'conv2d_10/Kernel' 1 49 [80, 1, 1, 72]\n",
      " 99              b'conv2d_10/Bias' 1 50 [80]\n",
      "100                   b'conv2d_10' 0  0 [1, 16, 16, 80]\n",
      "101  b'channel_padding_8/Paddings' 2 51 [4, 2]\n",
      "102           b'channel_padding_8' 0  0 [1, 16, 16, 80]\n",
      "103       b'add_9__xeno_compat__1' 0  0 [1, 16, 16, 80]\n",
      "104               b'activation_10' 0  0 [1, 16, 16, 80]\n",
      "105  b'depthwise_conv2d_10/Kernel' 1 52 [1, 3, 3, 80]\n",
      "106    b'depthwise_conv2d_10/Bias' 1 53 [80]\n",
      "107         b'depthwise_conv2d_10' 0  0 [1, 16, 16, 80]\n",
      "108            b'conv2d_11/Kernel' 1 54 [88, 1, 1, 80]\n",
      "109              b'conv2d_11/Bias' 1 55 [88]\n",
      "110                   b'conv2d_11' 0  0 [1, 16, 16, 88]\n",
      "111  b'channel_padding_9/Paddings' 2 56 [4, 2]\n",
      "112           b'channel_padding_9' 0  0 [1, 16, 16, 88]\n",
      "113      b'add_10__xeno_compat__1' 0  0 [1, 16, 16, 88]\n",
      "114               b'activation_11' 0  0 [1, 16, 16, 88]\n",
      "115  b'depthwise_conv2d_11/Kernel' 1 57 [1, 3, 3, 88]\n",
      "116    b'depthwise_conv2d_11/Bias' 1 58 [88]\n",
      "117         b'depthwise_conv2d_11' 0  0 [1, 8, 8, 88]\n",
      "118             b'max_pooling2d_2' 0  0 [1, 8, 8, 88]\n",
      "119            b'conv2d_12/Kernel' 1 59 [96, 1, 1, 88]\n",
      "120              b'conv2d_12/Bias' 1 60 [96]\n",
      "121                   b'conv2d_12' 0  0 [1, 8, 8, 96]\n",
      "122 b'channel_padding_10/Paddings' 2 61 [4, 2]\n",
      "123          b'channel_padding_10' 0  0 [1, 8, 8, 96]\n",
      "124      b'add_11__xeno_compat__1' 0  0 [1, 8, 8, 96]\n",
      "125               b'activation_12' 0  0 [1, 8, 8, 96]\n",
      "126  b'depthwise_conv2d_12/Kernel' 1 62 [1, 3, 3, 96]\n",
      "127    b'depthwise_conv2d_12/Bias' 1 63 [96]\n",
      "128         b'depthwise_conv2d_12' 0  0 [1, 8, 8, 96]\n",
      "129            b'conv2d_13/Kernel' 1 64 [96, 1, 1, 96]\n",
      "130              b'conv2d_13/Bias' 1 65 [96]\n",
      "131                   b'conv2d_13' 0  0 [1, 8, 8, 96]\n",
      "132      b'add_12__xeno_compat__1' 0  0 [1, 8, 8, 96]\n",
      "133               b'activation_13' 0  0 [1, 8, 8, 96]\n",
      "134  b'depthwise_conv2d_13/Kernel' 1 66 [1, 3, 3, 96]\n",
      "135    b'depthwise_conv2d_13/Bias' 1 67 [96]\n",
      "136         b'depthwise_conv2d_13' 0  0 [1, 8, 8, 96]\n",
      "137            b'conv2d_14/Kernel' 1 68 [96, 1, 1, 96]\n",
      "138              b'conv2d_14/Bias' 1 69 [96]\n",
      "139                   b'conv2d_14' 0  0 [1, 8, 8, 96]\n",
      "140      b'add_13__xeno_compat__1' 0  0 [1, 8, 8, 96]\n",
      "141               b'activation_14' 0  0 [1, 8, 8, 96]\n",
      "142  b'depthwise_conv2d_14/Kernel' 1 70 [1, 3, 3, 96]\n",
      "143    b'depthwise_conv2d_14/Bias' 1 71 [96]\n",
      "144         b'depthwise_conv2d_14' 0  0 [1, 8, 8, 96]\n",
      "145            b'conv2d_15/Kernel' 1 72 [96, 1, 1, 96]\n",
      "146              b'conv2d_15/Bias' 1 73 [96]\n",
      "147                   b'conv2d_15' 0  0 [1, 8, 8, 96]\n",
      "148      b'add_14__xeno_compat__1' 0  0 [1, 8, 8, 96]\n",
      "149               b'activation_15' 0  0 [1, 8, 8, 96]\n",
      "150  b'depthwise_conv2d_15/Kernel' 1 74 [1, 3, 3, 96]\n",
      "151    b'depthwise_conv2d_15/Bias' 1 75 [96]\n",
      "152         b'depthwise_conv2d_15' 0  0 [1, 8, 8, 96]\n",
      "153            b'conv2d_16/Kernel' 1 76 [96, 1, 1, 96]\n",
      "154              b'conv2d_16/Bias' 1 77 [96]\n",
      "155                   b'conv2d_16' 0  0 [1, 8, 8, 96]\n",
      "156      b'add_15__xeno_compat__1' 0  0 [1, 8, 8, 96]\n",
      "157               b'activation_16' 0  0 [1, 8, 8, 96]\n",
      "158      b'classificator_8/Kernel' 1 78 [2, 1, 1, 88]\n",
      "159        b'classificator_8/Bias' 1 79 [2]\n",
      "160             b'classificator_8' 0  0 [1, 16, 16, 2]\n",
      "161     b'classificator_16/Kernel' 1 80 [6, 1, 1, 96]\n",
      "162       b'classificator_16/Bias' 1 81 [6]\n",
      "163            b'classificator_16' 0  0 [1, 8, 8, 6]\n",
      "164          b'regressor_8/Kernel' 1 82 [32, 1, 1, 88]\n",
      "165            b'regressor_8/Bias' 1 83 [32]\n",
      "166                 b'regressor_8' 0  0 [1, 16, 16, 32]\n",
      "167         b'regressor_16/Kernel' 1 84 [96, 1, 1, 96]\n",
      "168           b'regressor_16/Bias' 1 85 [96]\n",
      "169                b'regressor_16' 0  0 [1, 8, 8, 96]\n",
      "170                     b'reshape' 0  0 [1, 512, 1]\n",
      "171                   b'reshape_2' 0  0 [1, 384, 1]\n",
      "172                   b'reshape_1' 0  0 [1, 512, 16]\n",
      "173                   b'reshape_3' 0  0 [1, 384, 16]\n",
      "174              b'classificators' 0  0 [1, 896, 1]\n",
      "175                  b'regressors' 0  0 [1, 896, 16]\n",
      "176    b'conv2d_3/Bias_dequantize' 0  0 [32]\n",
      "177   b'conv2d_16/Bias_dequantize' 0  0 [96]\n",
      "178    b'conv2d_2/Bias_dequantize' 0  0 [28]\n",
      "179 b'depthwise_conv2d_3/Bias_dequantize' 0  0 [32]\n",
      "180 b'depthwise_conv2d_14/Bias_dequantize' 0  0 [96]\n",
      "181 b'classificator_16/Kernel_dequantize' 0  0 [6, 1, 1, 96]\n",
      "182    b'conv2d_9/Bias_dequantize' 0  0 [72]\n",
      "183 b'regressor_16/Bias_dequantize' 0  0 [96]\n",
      "184 b'depthwise_conv2d_2/Bias_dequantize' 0  0 [28]\n",
      "185 b'depthwise_conv2d/Bias_dequantize' 0  0 [24]\n",
      "186 b'depthwise_conv2d_15/Kernel_dequantize' 0  0 [1, 3, 3, 96]\n",
      "187  b'conv2d_8/Kernel_dequantize' 0  0 [64, 1, 1, 56]\n",
      "188 b'depthwise_conv2d_9/Bias_dequantize' 0  0 [72]\n",
      "189 b'depthwise_conv2d_1/Kernel_dequantize' 0  0 [1, 3, 3, 24]\n",
      "190 b'regressor_8/Kernel_dequantize' 0  0 [32, 1, 1, 88]\n",
      "191   b'conv2d_15/Bias_dequantize' 0  0 [96]\n",
      "192 b'depthwise_conv2d_8/Kernel_dequantize' 0  0 [1, 3, 3, 64]\n",
      "193      b'conv2d/Bias_dequantize' 0  0 [24]\n",
      "194 b'conv2d_16/Kernel_dequantize' 0  0 [96, 1, 1, 96]\n",
      "195   b'conv2d_10/Bias_dequantize' 0  0 [80]\n",
      "196 b'depthwise_conv2d_13/Bias_dequantize' 0  0 [96]\n",
      "197    b'conv2d_4/Bias_dequantize' 0  0 [36]\n",
      "198 b'depthwise_conv2d_14/Kernel_dequantize' 0  0 [1, 3, 3, 96]\n",
      "199  b'conv2d_9/Kernel_dequantize' 0  0 [72, 1, 1, 64]\n",
      "200 b'depthwise_conv2d_10/Bias_dequantize' 0  0 [80]\n",
      "201  b'conv2d_3/Kernel_dequantize' 0  0 [32, 1, 1, 28]\n",
      "202 b'depthwise_conv2d_4/Bias_dequantize' 0  0 [36]\n",
      "203    b'conv2d_1/Bias_dequantize' 0  0 [24]\n",
      "204    b'conv2d_6/Bias_dequantize' 0  0 [48]\n",
      "205 b'depthwise_conv2d_9/Kernel_dequantize' 0  0 [1, 3, 3, 72]\n",
      "206 b'depthwise_conv2d_3/Kernel_dequantize' 0  0 [1, 3, 3, 32]\n",
      "207  b'conv2d_2/Kernel_dequantize' 0  0 [28, 1, 1, 24]\n",
      "208 b'regressor_16/Kernel_dequantize' 0  0 [96, 1, 1, 96]\n",
      "209   b'conv2d_12/Bias_dequantize' 0  0 [96]\n",
      "210    b'conv2d_5/Bias_dequantize' 0  0 [42]\n",
      "211 b'depthwise_conv2d_6/Bias_dequantize' 0  0 [48]\n",
      "212 b'depthwise_conv2d_2/Kernel_dequantize' 0  0 [1, 3, 3, 28]\n",
      "213   b'conv2d_14/Bias_dequantize' 0  0 [96]\n",
      "214 b'depthwise_conv2d/Kernel_dequantize' 0  0 [1, 3, 3, 24]\n",
      "215  b'conv2d_4/Kernel_dequantize' 0  0 [36, 1, 1, 32]\n",
      "216 b'depthwise_conv2d_5/Bias_dequantize' 0  0 [42]\n",
      "217   b'conv2d_11/Bias_dequantize' 0  0 [88]\n",
      "218 b'depthwise_conv2d_12/Bias_dequantize' 0  0 [96]\n",
      "219 b'depthwise_conv2d_4/Kernel_dequantize' 0  0 [1, 3, 3, 36]\n",
      "220 b'conv2d_15/Kernel_dequantize' 0  0 [96, 1, 1, 96]\n",
      "221  b'conv2d_1/Kernel_dequantize' 0  0 [24, 1, 1, 24]\n",
      "222 b'classificator_8/Bias_dequantize' 0  0 [2]\n",
      "223 b'depthwise_conv2d_13/Kernel_dequantize' 0  0 [1, 3, 3, 96]\n",
      "224    b'conv2d/Kernel_dequantize' 0  0 [24, 5, 5, 3]\n",
      "225 b'conv2d_10/Kernel_dequantize' 0  0 [80, 1, 1, 72]\n",
      "226 b'depthwise_conv2d_11/Bias_dequantize' 0  0 [88]\n",
      "227    b'conv2d_7/Bias_dequantize' 0  0 [56]\n",
      "228 b'depthwise_conv2d_10/Kernel_dequantize' 0  0 [1, 3, 3, 80]\n",
      "229 b'conv2d_12/Kernel_dequantize' 0  0 [96, 1, 1, 88]\n",
      "230 b'conv2d_14/Kernel_dequantize' 0  0 [96, 1, 1, 96]\n",
      "231   b'conv2d_13/Bias_dequantize' 0  0 [96]\n",
      "232  b'conv2d_6/Kernel_dequantize' 0  0 [48, 1, 1, 42]\n",
      "233 b'depthwise_conv2d_7/Bias_dequantize' 0  0 [56]\n",
      "234 b'classificator_16/Bias_dequantize' 0  0 [6]\n",
      "235 b'conv2d_11/Kernel_dequantize' 0  0 [88, 1, 1, 80]\n",
      "236 b'depthwise_conv2d_12/Kernel_dequantize' 0  0 [1, 3, 3, 96]\n",
      "237  b'conv2d_5/Kernel_dequantize' 0  0 [42, 1, 1, 36]\n",
      "238 b'depthwise_conv2d_6/Kernel_dequantize' 0  0 [1, 3, 3, 48]\n",
      "239 b'depthwise_conv2d_15/Bias_dequantize' 0  0 [96]\n",
      "240    b'conv2d_8/Bias_dequantize' 0  0 [64]\n",
      "241 b'depthwise_conv2d_11/Kernel_dequantize' 0  0 [1, 3, 3, 88]\n",
      "242 b'depthwise_conv2d_5/Kernel_dequantize' 0  0 [1, 3, 3, 42]\n",
      "243  b'conv2d_7/Kernel_dequantize' 0  0 [56, 1, 1, 48]\n",
      "244 b'depthwise_conv2d_8/Bias_dequantize' 0  0 [64]\n",
      "245 b'classificator_8/Kernel_dequantize' 0  0 [2, 1, 1, 88]\n",
      "246 b'depthwise_conv2d_7/Kernel_dequantize' 0  0 [1, 3, 3, 56]\n",
      "247 b'depthwise_conv2d_1/Bias_dequantize' 0  0 [24]\n",
      "248 b'regressor_8/Bias_dequantize' 0  0 [32]\n",
      "249 b'conv2d_13/Kernel_dequantize' 0  0 [96, 1, 1, 96]\n"
     ]
    }
   ],
   "source": [
    "def print_graph(graph):\n",
    "    for i in range(0, graph.TensorsLength()):\n",
    "        tensor = graph.Tensors(i)\n",
    "        print(\"%3d %30s %d %2d %s\" % (i, tensor.Name(), tensor.Type(), tensor.Buffer(), \n",
    "                                      get_shape(graph.Tensors(i))))\n",
    "\n",
    "print_graph(front_subgraph)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Make a look-up table that lets us get the tensor index based on the tensor name:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "front_tensor_dict = {(front_subgraph.Tensors(i).Name().decode(\"utf8\")): i \n",
    "               for i in range(front_subgraph.TensorsLength())}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Grab only the tensors that represent weights and biases."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "85"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def get_parameters(graph):\n",
    "    parameters = {}\n",
    "    for i in range(graph.TensorsLength()):\n",
    "        tensor = graph.Tensors(i)\n",
    "        if tensor.Buffer() > 0:\n",
    "            name = tensor.Name().decode(\"utf8\")\n",
    "            parameters[name] = tensor.Buffer()\n",
    "    return parameters\n",
    "\n",
    "front_parameters = get_parameters(front_subgraph)\n",
    "len(front_parameters)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The buffers are simply arrays of bytes. As the docs say,\n",
    "\n",
    "> The data_buffer itself is an opaque container, with the assumption that the\n",
    "> target device is little-endian. In addition, all builtin operators assume\n",
    "> the memory is ordered such that if `shape` is [4, 3, 2], then index\n",
    "> [i, j, k] maps to `data_buffer[i*3*2 + j*2 + k]`.\n",
    "\n",
    "For weights and biases, we need to interpret every 4 bytes as being as float. On my machine, the native byte ordering is already little-endian so we don't need to do anything special for that.\n",
    "\n",
    "Found some weights and biases stored as float16 instead of float32 corresponding to Type 1 instead of 0."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_weights(model, graph, tensor_dict, tensor_name):\n",
    "    i = tensor_dict[tensor_name]\n",
    "    tensor = graph.Tensors(i)\n",
    "    buffer = tensor.Buffer()\n",
    "    shape = get_shape(tensor)\n",
    "    assert(tensor.Type() == 0 or tensor.Type() == 1)  # FLOAT32\n",
    "    \n",
    "    W = model.Buffers(buffer).DataAsNumpy()\n",
    "    if tensor.Type() == 0:\n",
    "        W = W.view(dtype=np.float32)\n",
    "    elif tensor.Type() == 1:\n",
    "        W = W.view(dtype=np.float16)\n",
    "    W = W.reshape(shape)\n",
    "    return W"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((24, 5, 5, 3), (24,))"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "W = get_weights(front_model, front_subgraph, front_tensor_dict, \"conv2d/Kernel\")\n",
    "b = get_weights(front_model, front_subgraph, front_tensor_dict, \"conv2d/Bias\")\n",
    "W.shape, b.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we can get the weights for all the layers and copy them into our PyTorch model."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Convert the weights to PyTorch format"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "import torch\n",
    "from blazeface import BlazeFace"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "front_net = BlazeFace()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "BlazeFace(\n",
       "  (backbone1): Sequential(\n",
       "    (0): Conv2d(3, 24, kernel_size=(5, 5), stride=(2, 2))\n",
       "    (1): ReLU(inplace=True)\n",
       "    (2): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(24, 24, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=24)\n",
       "        (1): Conv2d(24, 24, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (3): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(24, 24, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=24)\n",
       "        (1): Conv2d(24, 28, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (4): BlazeBlock(\n",
       "      (max_pool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(28, 28, kernel_size=(3, 3), stride=(2, 2), groups=28)\n",
       "        (1): Conv2d(28, 32, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (5): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=32)\n",
       "        (1): Conv2d(32, 36, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (6): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(36, 36, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=36)\n",
       "        (1): Conv2d(36, 42, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (7): BlazeBlock(\n",
       "      (max_pool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(42, 42, kernel_size=(3, 3), stride=(2, 2), groups=42)\n",
       "        (1): Conv2d(42, 48, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (8): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(48, 48, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=48)\n",
       "        (1): Conv2d(48, 56, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (9): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(56, 56, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=56)\n",
       "        (1): Conv2d(56, 64, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (10): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=64)\n",
       "        (1): Conv2d(64, 72, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (11): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(72, 72, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=72)\n",
       "        (1): Conv2d(72, 80, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (12): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(80, 80, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=80)\n",
       "        (1): Conv2d(80, 88, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "  )\n",
       "  (backbone2): Sequential(\n",
       "    (0): BlazeBlock(\n",
       "      (max_pool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(88, 88, kernel_size=(3, 3), stride=(2, 2), groups=88)\n",
       "        (1): Conv2d(88, 96, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (1): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(96, 96, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=96)\n",
       "        (1): Conv2d(96, 96, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (2): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(96, 96, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=96)\n",
       "        (1): Conv2d(96, 96, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (3): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(96, 96, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=96)\n",
       "        (1): Conv2d(96, 96, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (4): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(96, 96, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=96)\n",
       "        (1): Conv2d(96, 96, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "  )\n",
       "  (classifier_8): Conv2d(88, 2, kernel_size=(1, 1), stride=(1, 1))\n",
       "  (classifier_16): Conv2d(96, 6, kernel_size=(1, 1), stride=(1, 1))\n",
       "  (regressor_8): Conv2d(88, 32, kernel_size=(1, 1), stride=(1, 1))\n",
       "  (regressor_16): Conv2d(96, 96, kernel_size=(1, 1), stride=(1, 1))\n",
       ")"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "front_net"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Make a lookup table that maps the layer names between the two models. We're going to assume here that the tensors will be in the same order in both models. If not, we should get an error because shapes don't match."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['conv2d/Kernel',\n",
       " 'conv2d/Bias',\n",
       " 'depthwise_conv2d/Kernel',\n",
       " 'depthwise_conv2d/Bias',\n",
       " 'conv2d_1/Kernel']"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def get_probable_names(graph):\n",
    "    probable_names = []\n",
    "    for i in range(0, graph.TensorsLength()):\n",
    "        tensor = graph.Tensors(i)\n",
    "        if tensor.Buffer() > 0 and (tensor.Type() == 0 or tensor.Type() == 1):\n",
    "            probable_names.append(tensor.Name().decode(\"utf-8\"))\n",
    "    return probable_names\n",
    "\n",
    "front_probable_names = get_probable_names(front_subgraph)\n",
    "        \n",
    "front_probable_names[:5]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_convert(net, probable_names):\n",
    "    convert = {}\n",
    "    i = 0\n",
    "    for name, params in net.state_dict().items():\n",
    "        convert[name] = probable_names[i]\n",
    "        i += 1\n",
    "    return convert\n",
    "\n",
    "front_convert = get_convert(front_net, front_probable_names)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Copy the weights into the layers.\n",
    "\n",
    "Note that the ordering of the weights is different between PyTorch and TFLite, so we need to transpose them.\n",
    "\n",
    "Convolution weights:\n",
    "\n",
    "    TFLite:  (out_channels, kernel_height, kernel_width, in_channels)\n",
    "    PyTorch: (out_channels, in_channels, kernel_height, kernel_width)\n",
    "\n",
    "Depthwise convolution weights:\n",
    "\n",
    "    TFLite:  (1, kernel_height, kernel_width, channels)\n",
    "    PyTorch: (channels, 1, kernel_height, kernel_width)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "backbone1.0.weight conv2d/Kernel (24, 5, 5, 3) torch.Size([24, 3, 5, 5])\n",
      "backbone1.0.bias conv2d/Bias (24,) torch.Size([24])\n",
      "backbone1.2.convs.0.weight depthwise_conv2d/Kernel (1, 3, 3, 24) torch.Size([24, 1, 3, 3])\n",
      "backbone1.2.convs.0.bias depthwise_conv2d/Bias (24,) torch.Size([24])\n",
      "backbone1.2.convs.1.weight conv2d_1/Kernel (24, 1, 1, 24) torch.Size([24, 24, 1, 1])\n",
      "backbone1.2.convs.1.bias conv2d_1/Bias (24,) torch.Size([24])\n",
      "backbone1.3.convs.0.weight depthwise_conv2d_1/Kernel (1, 3, 3, 24) torch.Size([24, 1, 3, 3])\n",
      "backbone1.3.convs.0.bias depthwise_conv2d_1/Bias (24,) torch.Size([24])\n",
      "backbone1.3.convs.1.weight conv2d_2/Kernel (28, 1, 1, 24) torch.Size([28, 24, 1, 1])\n",
      "backbone1.3.convs.1.bias conv2d_2/Bias (28,) torch.Size([28])\n",
      "backbone1.4.convs.0.weight depthwise_conv2d_2/Kernel (1, 3, 3, 28) torch.Size([28, 1, 3, 3])\n",
      "backbone1.4.convs.0.bias depthwise_conv2d_2/Bias (28,) torch.Size([28])\n",
      "backbone1.4.convs.1.weight conv2d_3/Kernel (32, 1, 1, 28) torch.Size([32, 28, 1, 1])\n",
      "backbone1.4.convs.1.bias conv2d_3/Bias (32,) torch.Size([32])\n",
      "backbone1.5.convs.0.weight depthwise_conv2d_3/Kernel (1, 3, 3, 32) torch.Size([32, 1, 3, 3])\n",
      "backbone1.5.convs.0.bias depthwise_conv2d_3/Bias (32,) torch.Size([32])\n",
      "backbone1.5.convs.1.weight conv2d_4/Kernel (36, 1, 1, 32) torch.Size([36, 32, 1, 1])\n",
      "backbone1.5.convs.1.bias conv2d_4/Bias (36,) torch.Size([36])\n",
      "backbone1.6.convs.0.weight depthwise_conv2d_4/Kernel (1, 3, 3, 36) torch.Size([36, 1, 3, 3])\n",
      "backbone1.6.convs.0.bias depthwise_conv2d_4/Bias (36,) torch.Size([36])\n",
      "backbone1.6.convs.1.weight conv2d_5/Kernel (42, 1, 1, 36) torch.Size([42, 36, 1, 1])\n",
      "backbone1.6.convs.1.bias conv2d_5/Bias (42,) torch.Size([42])\n",
      "backbone1.7.convs.0.weight depthwise_conv2d_5/Kernel (1, 3, 3, 42) torch.Size([42, 1, 3, 3])\n",
      "backbone1.7.convs.0.bias depthwise_conv2d_5/Bias (42,) torch.Size([42])\n",
      "backbone1.7.convs.1.weight conv2d_6/Kernel (48, 1, 1, 42) torch.Size([48, 42, 1, 1])\n",
      "backbone1.7.convs.1.bias conv2d_6/Bias (48,) torch.Size([48])\n",
      "backbone1.8.convs.0.weight depthwise_conv2d_6/Kernel (1, 3, 3, 48) torch.Size([48, 1, 3, 3])\n",
      "backbone1.8.convs.0.bias depthwise_conv2d_6/Bias (48,) torch.Size([48])\n",
      "backbone1.8.convs.1.weight conv2d_7/Kernel (56, 1, 1, 48) torch.Size([56, 48, 1, 1])\n",
      "backbone1.8.convs.1.bias conv2d_7/Bias (56,) torch.Size([56])\n",
      "backbone1.9.convs.0.weight depthwise_conv2d_7/Kernel (1, 3, 3, 56) torch.Size([56, 1, 3, 3])\n",
      "backbone1.9.convs.0.bias depthwise_conv2d_7/Bias (56,) torch.Size([56])\n",
      "backbone1.9.convs.1.weight conv2d_8/Kernel (64, 1, 1, 56) torch.Size([64, 56, 1, 1])\n",
      "backbone1.9.convs.1.bias conv2d_8/Bias (64,) torch.Size([64])\n",
      "backbone1.10.convs.0.weight depthwise_conv2d_8/Kernel (1, 3, 3, 64) torch.Size([64, 1, 3, 3])\n",
      "backbone1.10.convs.0.bias depthwise_conv2d_8/Bias (64,) torch.Size([64])\n",
      "backbone1.10.convs.1.weight conv2d_9/Kernel (72, 1, 1, 64) torch.Size([72, 64, 1, 1])\n",
      "backbone1.10.convs.1.bias conv2d_9/Bias (72,) torch.Size([72])\n",
      "backbone1.11.convs.0.weight depthwise_conv2d_9/Kernel (1, 3, 3, 72) torch.Size([72, 1, 3, 3])\n",
      "backbone1.11.convs.0.bias depthwise_conv2d_9/Bias (72,) torch.Size([72])\n",
      "backbone1.11.convs.1.weight conv2d_10/Kernel (80, 1, 1, 72) torch.Size([80, 72, 1, 1])\n",
      "backbone1.11.convs.1.bias conv2d_10/Bias (80,) torch.Size([80])\n",
      "backbone1.12.convs.0.weight depthwise_conv2d_10/Kernel (1, 3, 3, 80) torch.Size([80, 1, 3, 3])\n",
      "backbone1.12.convs.0.bias depthwise_conv2d_10/Bias (80,) torch.Size([80])\n",
      "backbone1.12.convs.1.weight conv2d_11/Kernel (88, 1, 1, 80) torch.Size([88, 80, 1, 1])\n",
      "backbone1.12.convs.1.bias conv2d_11/Bias (88,) torch.Size([88])\n",
      "backbone2.0.convs.0.weight depthwise_conv2d_11/Kernel (1, 3, 3, 88) torch.Size([88, 1, 3, 3])\n",
      "backbone2.0.convs.0.bias depthwise_conv2d_11/Bias (88,) torch.Size([88])\n",
      "backbone2.0.convs.1.weight conv2d_12/Kernel (96, 1, 1, 88) torch.Size([96, 88, 1, 1])\n",
      "backbone2.0.convs.1.bias conv2d_12/Bias (96,) torch.Size([96])\n",
      "backbone2.1.convs.0.weight depthwise_conv2d_12/Kernel (1, 3, 3, 96) torch.Size([96, 1, 3, 3])\n",
      "backbone2.1.convs.0.bias depthwise_conv2d_12/Bias (96,) torch.Size([96])\n",
      "backbone2.1.convs.1.weight conv2d_13/Kernel (96, 1, 1, 96) torch.Size([96, 96, 1, 1])\n",
      "backbone2.1.convs.1.bias conv2d_13/Bias (96,) torch.Size([96])\n",
      "backbone2.2.convs.0.weight depthwise_conv2d_13/Kernel (1, 3, 3, 96) torch.Size([96, 1, 3, 3])\n",
      "backbone2.2.convs.0.bias depthwise_conv2d_13/Bias (96,) torch.Size([96])\n",
      "backbone2.2.convs.1.weight conv2d_14/Kernel (96, 1, 1, 96) torch.Size([96, 96, 1, 1])\n",
      "backbone2.2.convs.1.bias conv2d_14/Bias (96,) torch.Size([96])\n",
      "backbone2.3.convs.0.weight depthwise_conv2d_14/Kernel (1, 3, 3, 96) torch.Size([96, 1, 3, 3])\n",
      "backbone2.3.convs.0.bias depthwise_conv2d_14/Bias (96,) torch.Size([96])\n",
      "backbone2.3.convs.1.weight conv2d_15/Kernel (96, 1, 1, 96) torch.Size([96, 96, 1, 1])\n",
      "backbone2.3.convs.1.bias conv2d_15/Bias (96,) torch.Size([96])\n",
      "backbone2.4.convs.0.weight depthwise_conv2d_15/Kernel (1, 3, 3, 96) torch.Size([96, 1, 3, 3])\n",
      "backbone2.4.convs.0.bias depthwise_conv2d_15/Bias (96,) torch.Size([96])\n",
      "backbone2.4.convs.1.weight conv2d_16/Kernel (96, 1, 1, 96) torch.Size([96, 96, 1, 1])\n",
      "backbone2.4.convs.1.bias conv2d_16/Bias (96,) torch.Size([96])\n",
      "classifier_8.weight classificator_8/Kernel (2, 1, 1, 88) torch.Size([2, 88, 1, 1])\n",
      "classifier_8.bias classificator_8/Bias (2,) torch.Size([2])\n",
      "classifier_16.weight classificator_16/Kernel (6, 1, 1, 96) torch.Size([6, 96, 1, 1])\n",
      "classifier_16.bias classificator_16/Bias (6,) torch.Size([6])\n",
      "regressor_8.weight regressor_8/Kernel (32, 1, 1, 88) torch.Size([32, 88, 1, 1])\n",
      "regressor_8.bias regressor_8/Bias (32,) torch.Size([32])\n",
      "regressor_16.weight regressor_16/Kernel (96, 1, 1, 96) torch.Size([96, 96, 1, 1])\n",
      "regressor_16.bias regressor_16/Bias (96,) torch.Size([96])\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "<ipython-input-16-48653ed74eb5>:14: UserWarning: The given NumPy array is not writeable, and PyTorch does not support non-writeable tensors. This means you can write to the underlying (supposedly non-writeable) NumPy array using the tensor. You may want to copy the array to protect its data or make it writeable before converting it to a tensor. This type of warning will be suppressed for the rest of this program. (Triggered internally at  /opt/conda/conda-bld/pytorch_1595629395347/work/torch/csrc/utils/tensor_numpy.cpp:141.)\n",
      "  new_state_dict[dst] = torch.from_numpy(W)\n"
     ]
    }
   ],
   "source": [
    "def build_state_dict(model, graph, tensor_dict, net, convert):\n",
    "    new_state_dict = OrderedDict()\n",
    "\n",
    "    for dst, src in convert.items():\n",
    "        W = get_weights(model, graph, tensor_dict, src)\n",
    "        print(dst, src, W.shape, net.state_dict()[dst].shape)\n",
    "\n",
    "        if W.ndim == 4:\n",
    "            if W.shape[0] == 1:\n",
    "                W = W.transpose((3, 0, 1, 2))  # depthwise conv\n",
    "            else:\n",
    "                W = W.transpose((0, 3, 1, 2))  # regular conv\n",
    "    \n",
    "        new_state_dict[dst] = torch.from_numpy(W)\n",
    "    return new_state_dict\n",
    "\n",
    "front_state_dict = build_state_dict(front_model, front_subgraph, front_tensor_dict, front_net, front_convert)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<All keys matched successfully>"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "front_net.load_state_dict(front_state_dict, strict=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "No errors? Then the conversion was successful!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Save the checkpoint"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "torch.save(front_net.state_dict(), \"blazeface.pth\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Convert back camera TFLite model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "--2021-02-09 23:19:58--  https://github.com/google/mediapipe/raw/master/mediapipe/models/face_detection_back.tflite\n",
      "Résolution de github.com (github.com)… 140.82.121.3\n",
      "Connexion à github.com (github.com)|140.82.121.3|:443… connecté.\n",
      "requête HTTP transmise, en attente de la réponse… 302 Found\n",
      "Emplacement : https://raw.githubusercontent.com/google/mediapipe/master/mediapipe/models/face_detection_back.tflite [suivant]\n",
      "--2021-02-09 23:19:58--  https://raw.githubusercontent.com/google/mediapipe/master/mediapipe/models/face_detection_back.tflite\n",
      "Résolution de raw.githubusercontent.com (raw.githubusercontent.com)… 151.101.120.133\n",
      "Connexion à raw.githubusercontent.com (raw.githubusercontent.com)|151.101.120.133|:443… connecté.\n",
      "requête HTTP transmise, en attente de la réponse… 200 OK\n",
      "Taille : 315332 (308K) [application/octet-stream]\n",
      "Enregistre : «face_detection_back.tflite»\n",
      "\n",
      "face_detection_back 100%[===================>] 307,94K  --.-KB/s    ds 0,02s   \n",
      "\n",
      "En-tête de dernière modification manquant — horodatage arrêté.\n",
      "2021-02-09 23:19:58 (17,0 MB/s) - «face_detection_back.tflite» enregistré [315332/315332]\n",
      "\n"
     ]
    }
   ],
   "source": [
    "!wget -N https://github.com/google/mediapipe/raw/master/mediapipe/models/face_detection_back.tflite"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "b'keras2tflite_facedetector-back.tflite.generated'"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "back_data = open(\"./face_detection_back.tflite\", \"rb\").read()\n",
    "back_model = Model.GetRootAsModel(back_data, 0)\n",
    "back_subgraph = back_model.Subgraphs(0)\n",
    "back_subgraph.Name()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  0                       b'input' 0  0 [1, 256, 256, 3]\n",
      "  1               b'conv2d/Kernel' 1  1 [24, 5, 5, 3]\n",
      "  2                 b'conv2d/Bias' 1  2 [24]\n",
      "  3                      b'conv2d' 0  0 [1, 128, 128, 24]\n",
      "  4                  b'activation' 0  0 [1, 128, 128, 24]\n",
      "  5     b'depthwise_conv2d/Kernel' 1  3 [1, 3, 3, 24]\n",
      "  6       b'depthwise_conv2d/Bias' 1  4 [24]\n",
      "  7            b'depthwise_conv2d' 0  0 [1, 128, 128, 24]\n",
      "  8             b'conv2d_1/Kernel' 1  5 [24, 1, 1, 24]\n",
      "  9               b'conv2d_1/Bias' 1  6 [24]\n",
      " 10                    b'conv2d_1' 0  0 [1, 128, 128, 24]\n",
      " 11                         b'add' 0  0 [1, 128, 128, 24]\n",
      " 12                b'activation_1' 0  0 [1, 128, 128, 24]\n",
      " 13   b'depthwise_conv2d_1/Kernel' 1  7 [1, 3, 3, 24]\n",
      " 14     b'depthwise_conv2d_1/Bias' 1  8 [24]\n",
      " 15          b'depthwise_conv2d_1' 0  0 [1, 128, 128, 24]\n",
      " 16             b'conv2d_2/Kernel' 1  9 [24, 1, 1, 24]\n",
      " 17               b'conv2d_2/Bias' 1 10 [24]\n",
      " 18                    b'conv2d_2' 0  0 [1, 128, 128, 24]\n",
      " 19                       b'add_1' 0  0 [1, 128, 128, 24]\n",
      " 20                b'activation_2' 0  0 [1, 128, 128, 24]\n",
      " 21   b'depthwise_conv2d_2/Kernel' 1 11 [1, 3, 3, 24]\n",
      " 22     b'depthwise_conv2d_2/Bias' 1 12 [24]\n",
      " 23          b'depthwise_conv2d_2' 0  0 [1, 128, 128, 24]\n",
      " 24             b'conv2d_3/Kernel' 1 13 [24, 1, 1, 24]\n",
      " 25               b'conv2d_3/Bias' 1 14 [24]\n",
      " 26                    b'conv2d_3' 0  0 [1, 128, 128, 24]\n",
      " 27                       b'add_2' 0  0 [1, 128, 128, 24]\n",
      " 28                b'activation_3' 0  0 [1, 128, 128, 24]\n",
      " 29   b'depthwise_conv2d_3/Kernel' 1 15 [1, 3, 3, 24]\n",
      " 30     b'depthwise_conv2d_3/Bias' 1 16 [24]\n",
      " 31          b'depthwise_conv2d_3' 0  0 [1, 128, 128, 24]\n",
      " 32             b'conv2d_4/Kernel' 1 17 [24, 1, 1, 24]\n",
      " 33               b'conv2d_4/Bias' 1 18 [24]\n",
      " 34                    b'conv2d_4' 0  0 [1, 128, 128, 24]\n",
      " 35                       b'add_3' 0  0 [1, 128, 128, 24]\n",
      " 36                b'activation_4' 0  0 [1, 128, 128, 24]\n",
      " 37   b'depthwise_conv2d_4/Kernel' 1 19 [1, 3, 3, 24]\n",
      " 38     b'depthwise_conv2d_4/Bias' 1 20 [24]\n",
      " 39          b'depthwise_conv2d_4' 0  0 [1, 128, 128, 24]\n",
      " 40             b'conv2d_5/Kernel' 1 21 [24, 1, 1, 24]\n",
      " 41               b'conv2d_5/Bias' 1 22 [24]\n",
      " 42                    b'conv2d_5' 0  0 [1, 128, 128, 24]\n",
      " 43                       b'add_4' 0  0 [1, 128, 128, 24]\n",
      " 44                b'activation_5' 0  0 [1, 128, 128, 24]\n",
      " 45   b'depthwise_conv2d_5/Kernel' 1 23 [1, 3, 3, 24]\n",
      " 46     b'depthwise_conv2d_5/Bias' 1 24 [24]\n",
      " 47          b'depthwise_conv2d_5' 0  0 [1, 128, 128, 24]\n",
      " 48             b'conv2d_6/Kernel' 1 25 [24, 1, 1, 24]\n",
      " 49               b'conv2d_6/Bias' 1 26 [24]\n",
      " 50                    b'conv2d_6' 0  0 [1, 128, 128, 24]\n",
      " 51                       b'add_5' 0  0 [1, 128, 128, 24]\n",
      " 52                b'activation_6' 0  0 [1, 128, 128, 24]\n",
      " 53   b'depthwise_conv2d_6/Kernel' 1 27 [1, 3, 3, 24]\n",
      " 54     b'depthwise_conv2d_6/Bias' 1 28 [24]\n",
      " 55          b'depthwise_conv2d_6' 0  0 [1, 128, 128, 24]\n",
      " 56             b'conv2d_7/Kernel' 1 29 [24, 1, 1, 24]\n",
      " 57               b'conv2d_7/Bias' 1 30 [24]\n",
      " 58                    b'conv2d_7' 0  0 [1, 128, 128, 24]\n",
      " 59                       b'add_6' 0  0 [1, 128, 128, 24]\n",
      " 60                b'activation_7' 0  0 [1, 128, 128, 24]\n",
      " 61   b'depthwise_conv2d_7/Kernel' 1 31 [1, 3, 3, 24]\n",
      " 62     b'depthwise_conv2d_7/Bias' 1 32 [24]\n",
      " 63          b'depthwise_conv2d_7' 0  0 [1, 64, 64, 24]\n",
      " 64             b'conv2d_8/Kernel' 1 33 [24, 1, 1, 24]\n",
      " 65               b'conv2d_8/Bias' 1 34 [24]\n",
      " 66                    b'conv2d_8' 0  0 [1, 64, 64, 24]\n",
      " 67               b'max_pooling2d' 0  0 [1, 64, 64, 24]\n",
      " 68                       b'add_7' 0  0 [1, 64, 64, 24]\n",
      " 69                b'activation_8' 0  0 [1, 64, 64, 24]\n",
      " 70   b'depthwise_conv2d_8/Kernel' 1 35 [1, 3, 3, 24]\n",
      " 71     b'depthwise_conv2d_8/Bias' 1 36 [24]\n",
      " 72          b'depthwise_conv2d_8' 0  0 [1, 64, 64, 24]\n",
      " 73             b'conv2d_9/Kernel' 1 37 [24, 1, 1, 24]\n",
      " 74               b'conv2d_9/Bias' 1 38 [24]\n",
      " 75                    b'conv2d_9' 0  0 [1, 64, 64, 24]\n",
      " 76                       b'add_8' 0  0 [1, 64, 64, 24]\n",
      " 77                b'activation_9' 0  0 [1, 64, 64, 24]\n",
      " 78   b'depthwise_conv2d_9/Kernel' 1 39 [1, 3, 3, 24]\n",
      " 79     b'depthwise_conv2d_9/Bias' 1 40 [24]\n",
      " 80          b'depthwise_conv2d_9' 0  0 [1, 64, 64, 24]\n",
      " 81            b'conv2d_10/Kernel' 1 41 [24, 1, 1, 24]\n",
      " 82              b'conv2d_10/Bias' 1 42 [24]\n",
      " 83                   b'conv2d_10' 0  0 [1, 64, 64, 24]\n",
      " 84                       b'add_9' 0  0 [1, 64, 64, 24]\n",
      " 85               b'activation_10' 0  0 [1, 64, 64, 24]\n",
      " 86  b'depthwise_conv2d_10/Kernel' 1 43 [1, 3, 3, 24]\n",
      " 87    b'depthwise_conv2d_10/Bias' 1 44 [24]\n",
      " 88         b'depthwise_conv2d_10' 0  0 [1, 64, 64, 24]\n",
      " 89            b'conv2d_11/Kernel' 1 45 [24, 1, 1, 24]\n",
      " 90              b'conv2d_11/Bias' 1 46 [24]\n",
      " 91                   b'conv2d_11' 0  0 [1, 64, 64, 24]\n",
      " 92                      b'add_10' 0  0 [1, 64, 64, 24]\n",
      " 93               b'activation_11' 0  0 [1, 64, 64, 24]\n",
      " 94  b'depthwise_conv2d_11/Kernel' 1 47 [1, 3, 3, 24]\n",
      " 95    b'depthwise_conv2d_11/Bias' 1 48 [24]\n",
      " 96         b'depthwise_conv2d_11' 0  0 [1, 64, 64, 24]\n",
      " 97            b'conv2d_12/Kernel' 1 49 [24, 1, 1, 24]\n",
      " 98              b'conv2d_12/Bias' 1 50 [24]\n",
      " 99                   b'conv2d_12' 0  0 [1, 64, 64, 24]\n",
      "100                      b'add_11' 0  0 [1, 64, 64, 24]\n",
      "101               b'activation_12' 0  0 [1, 64, 64, 24]\n",
      "102  b'depthwise_conv2d_12/Kernel' 1 51 [1, 3, 3, 24]\n",
      "103    b'depthwise_conv2d_12/Bias' 1 52 [24]\n",
      "104         b'depthwise_conv2d_12' 0  0 [1, 64, 64, 24]\n",
      "105            b'conv2d_13/Kernel' 1 53 [24, 1, 1, 24]\n",
      "106              b'conv2d_13/Bias' 1 54 [24]\n",
      "107                   b'conv2d_13' 0  0 [1, 64, 64, 24]\n",
      "108                      b'add_12' 0  0 [1, 64, 64, 24]\n",
      "109               b'activation_13' 0  0 [1, 64, 64, 24]\n",
      "110  b'depthwise_conv2d_13/Kernel' 1 55 [1, 3, 3, 24]\n",
      "111    b'depthwise_conv2d_13/Bias' 1 56 [24]\n",
      "112         b'depthwise_conv2d_13' 0  0 [1, 64, 64, 24]\n",
      "113            b'conv2d_14/Kernel' 1 57 [24, 1, 1, 24]\n",
      "114              b'conv2d_14/Bias' 1 58 [24]\n",
      "115                   b'conv2d_14' 0  0 [1, 64, 64, 24]\n",
      "116                      b'add_13' 0  0 [1, 64, 64, 24]\n",
      "117               b'activation_14' 0  0 [1, 64, 64, 24]\n",
      "118  b'depthwise_conv2d_14/Kernel' 1 59 [1, 3, 3, 24]\n",
      "119    b'depthwise_conv2d_14/Bias' 1 60 [24]\n",
      "120         b'depthwise_conv2d_14' 0  0 [1, 64, 64, 24]\n",
      "121            b'conv2d_15/Kernel' 1 61 [24, 1, 1, 24]\n",
      "122              b'conv2d_15/Bias' 1 62 [24]\n",
      "123                   b'conv2d_15' 0  0 [1, 64, 64, 24]\n",
      "124                      b'add_14' 0  0 [1, 64, 64, 24]\n",
      "125               b'activation_15' 0  0 [1, 64, 64, 24]\n",
      "126  b'depthwise_conv2d_15/Kernel' 1 63 [1, 3, 3, 24]\n",
      "127    b'depthwise_conv2d_15/Bias' 1 64 [24]\n",
      "128         b'depthwise_conv2d_15' 0  0 [1, 32, 32, 24]\n",
      "129             b'max_pooling2d_1' 0  0 [1, 32, 32, 24]\n",
      "130            b'conv2d_16/Kernel' 1 65 [48, 1, 1, 24]\n",
      "131              b'conv2d_16/Bias' 1 66 [48]\n",
      "132                   b'conv2d_16' 0  0 [1, 32, 32, 48]\n",
      "133    b'channel_padding/Paddings' 2 67 [4, 2]\n",
      "134             b'channel_padding' 0  0 [1, 32, 32, 48]\n",
      "135                      b'add_15' 0  0 [1, 32, 32, 48]\n",
      "136               b'activation_16' 0  0 [1, 32, 32, 48]\n",
      "137  b'depthwise_conv2d_16/Kernel' 1 68 [1, 3, 3, 48]\n",
      "138    b'depthwise_conv2d_16/Bias' 1 69 [48]\n",
      "139         b'depthwise_conv2d_16' 0  0 [1, 32, 32, 48]\n",
      "140            b'conv2d_17/Kernel' 1 70 [48, 1, 1, 48]\n",
      "141              b'conv2d_17/Bias' 1 71 [48]\n",
      "142                   b'conv2d_17' 0  0 [1, 32, 32, 48]\n",
      "143                      b'add_16' 0  0 [1, 32, 32, 48]\n",
      "144               b'activation_17' 0  0 [1, 32, 32, 48]\n",
      "145  b'depthwise_conv2d_17/Kernel' 1 72 [1, 3, 3, 48]\n",
      "146    b'depthwise_conv2d_17/Bias' 1 73 [48]\n",
      "147         b'depthwise_conv2d_17' 0  0 [1, 32, 32, 48]\n",
      "148            b'conv2d_18/Kernel' 1 74 [48, 1, 1, 48]\n",
      "149              b'conv2d_18/Bias' 1 75 [48]\n",
      "150                   b'conv2d_18' 0  0 [1, 32, 32, 48]\n",
      "151                      b'add_17' 0  0 [1, 32, 32, 48]\n",
      "152               b'activation_18' 0  0 [1, 32, 32, 48]\n",
      "153  b'depthwise_conv2d_18/Kernel' 1 76 [1, 3, 3, 48]\n",
      "154    b'depthwise_conv2d_18/Bias' 1 77 [48]\n",
      "155         b'depthwise_conv2d_18' 0  0 [1, 32, 32, 48]\n",
      "156            b'conv2d_19/Kernel' 1 78 [48, 1, 1, 48]\n",
      "157              b'conv2d_19/Bias' 1 79 [48]\n",
      "158                   b'conv2d_19' 0  0 [1, 32, 32, 48]\n",
      "159                      b'add_18' 0  0 [1, 32, 32, 48]\n",
      "160               b'activation_19' 0  0 [1, 32, 32, 48]\n",
      "161  b'depthwise_conv2d_19/Kernel' 1 80 [1, 3, 3, 48]\n",
      "162    b'depthwise_conv2d_19/Bias' 1 81 [48]\n",
      "163         b'depthwise_conv2d_19' 0  0 [1, 32, 32, 48]\n",
      "164            b'conv2d_20/Kernel' 1 82 [48, 1, 1, 48]\n",
      "165              b'conv2d_20/Bias' 1 83 [48]\n",
      "166                   b'conv2d_20' 0  0 [1, 32, 32, 48]\n",
      "167                      b'add_19' 0  0 [1, 32, 32, 48]\n",
      "168               b'activation_20' 0  0 [1, 32, 32, 48]\n",
      "169  b'depthwise_conv2d_20/Kernel' 1 84 [1, 3, 3, 48]\n",
      "170    b'depthwise_conv2d_20/Bias' 1 85 [48]\n",
      "171         b'depthwise_conv2d_20' 0  0 [1, 32, 32, 48]\n",
      "172            b'conv2d_21/Kernel' 1 86 [48, 1, 1, 48]\n",
      "173              b'conv2d_21/Bias' 1 87 [48]\n",
      "174                   b'conv2d_21' 0  0 [1, 32, 32, 48]\n",
      "175                      b'add_20' 0  0 [1, 32, 32, 48]\n",
      "176               b'activation_21' 0  0 [1, 32, 32, 48]\n",
      "177  b'depthwise_conv2d_21/Kernel' 1 88 [1, 3, 3, 48]\n",
      "178    b'depthwise_conv2d_21/Bias' 1 89 [48]\n",
      "179         b'depthwise_conv2d_21' 0  0 [1, 32, 32, 48]\n",
      "180            b'conv2d_22/Kernel' 1 90 [48, 1, 1, 48]\n",
      "181              b'conv2d_22/Bias' 1 91 [48]\n",
      "182                   b'conv2d_22' 0  0 [1, 32, 32, 48]\n",
      "183                      b'add_21' 0  0 [1, 32, 32, 48]\n",
      "184               b'activation_22' 0  0 [1, 32, 32, 48]\n",
      "185  b'depthwise_conv2d_22/Kernel' 1 92 [1, 3, 3, 48]\n",
      "186    b'depthwise_conv2d_22/Bias' 1 93 [48]\n",
      "187         b'depthwise_conv2d_22' 0  0 [1, 32, 32, 48]\n",
      "188            b'conv2d_23/Kernel' 1 94 [48, 1, 1, 48]\n",
      "189              b'conv2d_23/Bias' 1 95 [48]\n",
      "190                   b'conv2d_23' 0  0 [1, 32, 32, 48]\n",
      "191                      b'add_22' 0  0 [1, 32, 32, 48]\n",
      "192               b'activation_23' 0  0 [1, 32, 32, 48]\n",
      "193  b'depthwise_conv2d_23/Kernel' 1 96 [1, 3, 3, 48]\n",
      "194    b'depthwise_conv2d_23/Bias' 1 97 [48]\n",
      "195         b'depthwise_conv2d_23' 0  0 [1, 16, 16, 48]\n",
      "196             b'max_pooling2d_2' 0  0 [1, 16, 16, 48]\n",
      "197            b'conv2d_24/Kernel' 1 98 [96, 1, 1, 48]\n",
      "198              b'conv2d_24/Bias' 1 99 [96]\n",
      "199                   b'conv2d_24' 0  0 [1, 16, 16, 96]\n",
      "200  b'channel_padding_1/Paddings' 2 100 [4, 2]\n",
      "201           b'channel_padding_1' 0  0 [1, 16, 16, 96]\n",
      "202                      b'add_23' 0  0 [1, 16, 16, 96]\n",
      "203               b'activation_24' 0  0 [1, 16, 16, 96]\n",
      "204  b'depthwise_conv2d_24/Kernel' 1 101 [1, 3, 3, 96]\n",
      "205    b'depthwise_conv2d_24/Bias' 1 102 [96]\n",
      "206         b'depthwise_conv2d_24' 0  0 [1, 16, 16, 96]\n",
      "207            b'conv2d_25/Kernel' 1 103 [96, 1, 1, 96]\n",
      "208              b'conv2d_25/Bias' 1 104 [96]\n",
      "209                   b'conv2d_25' 0  0 [1, 16, 16, 96]\n",
      "210                      b'add_24' 0  0 [1, 16, 16, 96]\n",
      "211               b'activation_25' 0  0 [1, 16, 16, 96]\n",
      "212  b'depthwise_conv2d_25/Kernel' 1 105 [1, 3, 3, 96]\n",
      "213    b'depthwise_conv2d_25/Bias' 1 106 [96]\n",
      "214         b'depthwise_conv2d_25' 0  0 [1, 16, 16, 96]\n",
      "215            b'conv2d_26/Kernel' 1 107 [96, 1, 1, 96]\n",
      "216              b'conv2d_26/Bias' 1 108 [96]\n",
      "217                   b'conv2d_26' 0  0 [1, 16, 16, 96]\n",
      "218                      b'add_25' 0  0 [1, 16, 16, 96]\n",
      "219               b'activation_26' 0  0 [1, 16, 16, 96]\n",
      "220  b'depthwise_conv2d_26/Kernel' 1 109 [1, 3, 3, 96]\n",
      "221    b'depthwise_conv2d_26/Bias' 1 110 [96]\n",
      "222         b'depthwise_conv2d_26' 0  0 [1, 16, 16, 96]\n",
      "223            b'conv2d_27/Kernel' 1 111 [96, 1, 1, 96]\n",
      "224              b'conv2d_27/Bias' 1 112 [96]\n",
      "225                   b'conv2d_27' 0  0 [1, 16, 16, 96]\n",
      "226                      b'add_26' 0  0 [1, 16, 16, 96]\n",
      "227               b'activation_27' 0  0 [1, 16, 16, 96]\n",
      "228  b'depthwise_conv2d_27/Kernel' 1 113 [1, 3, 3, 96]\n",
      "229    b'depthwise_conv2d_27/Bias' 1 114 [96]\n",
      "230         b'depthwise_conv2d_27' 0  0 [1, 16, 16, 96]\n",
      "231            b'conv2d_28/Kernel' 1 115 [96, 1, 1, 96]\n",
      "232              b'conv2d_28/Bias' 1 116 [96]\n",
      "233                   b'conv2d_28' 0  0 [1, 16, 16, 96]\n",
      "234                      b'add_27' 0  0 [1, 16, 16, 96]\n",
      "235               b'activation_28' 0  0 [1, 16, 16, 96]\n",
      "236  b'depthwise_conv2d_28/Kernel' 1 117 [1, 3, 3, 96]\n",
      "237    b'depthwise_conv2d_28/Bias' 1 118 [96]\n",
      "238         b'depthwise_conv2d_28' 0  0 [1, 16, 16, 96]\n",
      "239            b'conv2d_29/Kernel' 1 119 [96, 1, 1, 96]\n",
      "240              b'conv2d_29/Bias' 1 120 [96]\n",
      "241                   b'conv2d_29' 0  0 [1, 16, 16, 96]\n",
      "242                      b'add_28' 0  0 [1, 16, 16, 96]\n",
      "243               b'activation_29' 0  0 [1, 16, 16, 96]\n",
      "244  b'depthwise_conv2d_29/Kernel' 1 121 [1, 3, 3, 96]\n",
      "245    b'depthwise_conv2d_29/Bias' 1 122 [96]\n",
      "246         b'depthwise_conv2d_29' 0  0 [1, 16, 16, 96]\n",
      "247            b'conv2d_30/Kernel' 1 123 [96, 1, 1, 96]\n",
      "248              b'conv2d_30/Bias' 1 124 [96]\n",
      "249                   b'conv2d_30' 0  0 [1, 16, 16, 96]\n",
      "250                      b'add_29' 0  0 [1, 16, 16, 96]\n",
      "251               b'activation_30' 0  0 [1, 16, 16, 96]\n",
      "252  b'depthwise_conv2d_30/Kernel' 1 125 [1, 3, 3, 96]\n",
      "253    b'depthwise_conv2d_30/Bias' 1 126 [96]\n",
      "254         b'depthwise_conv2d_30' 0  0 [1, 16, 16, 96]\n",
      "255            b'conv2d_31/Kernel' 1 127 [96, 1, 1, 96]\n",
      "256              b'conv2d_31/Bias' 1 128 [96]\n",
      "257                   b'conv2d_31' 0  0 [1, 16, 16, 96]\n",
      "258                      b'add_30' 0  0 [1, 16, 16, 96]\n",
      "259               b'activation_31' 0  0 [1, 16, 16, 96]\n",
      "260 b'separable_conv2d__xeno_compat__depthwise/Kernel' 1 129 [1, 3, 3, 96]\n",
      "261 b'separable_conv2d__xeno_compat__depthwise/Bias' 1 130 [96]\n",
      "262 b'separable_conv2d__xeno_compat__depthwise' 0  0 [1, 8, 8, 96]\n",
      "263     b'separable_conv2d/Kernel' 1 131 [96, 1, 1, 96]\n",
      "264       b'separable_conv2d/Bias' 1 132 [96]\n",
      "265            b'separable_conv2d' 0  0 [1, 8, 8, 96]\n",
      "266               b'activation_32' 0  0 [1, 8, 8, 96]\n",
      "267     b'classificator_16/Kernel' 1 133 [2, 1, 1, 96]\n",
      "268       b'classificator_16/Bias' 1 134 [2]\n",
      "269            b'classificator_16' 0  0 [1, 16, 16, 2]\n",
      "270     b'classificator_32/Kernel' 1 135 [6, 1, 1, 96]\n",
      "271       b'classificator_32/Bias' 1 136 [6]\n",
      "272            b'classificator_32' 0  0 [1, 8, 8, 6]\n",
      "273         b'regressor_16/Kernel' 1 137 [32, 1, 1, 96]\n",
      "274           b'regressor_16/Bias' 1 138 [32]\n",
      "275                b'regressor_16' 0  0 [1, 16, 16, 32]\n",
      "276         b'regressor_32/Kernel' 1 139 [96, 1, 1, 96]\n",
      "277           b'regressor_32/Bias' 1 140 [96]\n",
      "278                b'regressor_32' 0  0 [1, 8, 8, 96]\n",
      "279                     b'reshape' 0  0 [1, 512, 1]\n",
      "280                   b'reshape_2' 0  0 [1, 384, 1]\n",
      "281                   b'reshape_1' 0  0 [1, 512, 16]\n",
      "282                   b'reshape_3' 0  0 [1, 384, 16]\n",
      "283              b'classificators' 0  0 [1, 896, 1]\n",
      "284                  b'regressors' 0  0 [1, 896, 16]\n",
      "285 b'depthwise_conv2d_22/Kernel_dequantize' 0  0 [1, 3, 3, 48]\n",
      "286   b'conv2d_18/Bias_dequantize' 0  0 [48]\n",
      "287 b'conv2d_14/Kernel_dequantize' 0  0 [24, 1, 1, 24]\n",
      "288 b'separable_conv2d/Bias_dequantize' 0  0 [96]\n",
      "289    b'conv2d_5/Bias_dequantize' 0  0 [24]\n",
      "290 b'depthwise_conv2d_27/Kernel_dequantize' 0  0 [1, 3, 3, 96]\n",
      "291 b'depthwise_conv2d_21/Bias_dequantize' 0  0 [48]\n",
      "292   b'conv2d_13/Bias_dequantize' 0  0 [24]\n",
      "293 b'depthwise_conv2d_26/Bias_dequantize' 0  0 [96]\n",
      "294 b'depthwise_conv2d_8/Kernel_dequantize' 0  0 [1, 3, 3, 24]\n",
      "295 b'conv2d_25/Kernel_dequantize' 0  0 [96, 1, 1, 96]\n",
      "296  b'conv2d_7/Kernel_dequantize' 0  0 [24, 1, 1, 24]\n",
      "297 b'depthwise_conv2d_28/Kernel_dequantize' 0  0 [1, 3, 3, 96]\n",
      "298    b'conv2d_6/Bias_dequantize' 0  0 [24]\n",
      "299 b'depthwise_conv2d_1/Kernel_dequantize' 0  0 [1, 3, 3, 24]\n",
      "300 b'conv2d_20/Kernel_dequantize' 0  0 [48, 1, 1, 48]\n",
      "301   b'conv2d_14/Bias_dequantize' 0  0 [24]\n",
      "302 b'depthwise_conv2d_9/Kernel_dequantize' 0  0 [1, 3, 3, 24]\n",
      "303 b'depthwise_conv2d_27/Bias_dequantize' 0  0 [96]\n",
      "304   b'conv2d_19/Bias_dequantize' 0  0 [48]\n",
      "305 b'depthwise_conv2d/Bias_dequantize' 0  0 [24]\n",
      "306 b'depthwise_conv2d_23/Kernel_dequantize' 0  0 [1, 3, 3, 48]\n",
      "307 b'conv2d_15/Kernel_dequantize' 0  0 [24, 1, 1, 24]\n",
      "308 b'depthwise_conv2d_8/Bias_dequantize' 0  0 [24]\n",
      "309 b'depthwise_conv2d_22/Bias_dequantize' 0  0 [48]\n",
      "310  b'conv2d_8/Kernel_dequantize' 0  0 [24, 1, 1, 24]\n",
      "311 b'conv2d_26/Kernel_dequantize' 0  0 [96, 1, 1, 96]\n",
      "312 b'depthwise_conv2d_1/Bias_dequantize' 0  0 [24]\n",
      "313   b'conv2d_20/Bias_dequantize' 0  0 [48]\n",
      "314    b'conv2d_7/Bias_dequantize' 0  0 [24]\n",
      "315 b'conv2d_21/Kernel_dequantize' 0  0 [48, 1, 1, 48]\n",
      "316 b'depthwise_conv2d_2/Kernel_dequantize' 0  0 [1, 3, 3, 24]\n",
      "317   b'conv2d_25/Bias_dequantize' 0  0 [96]\n",
      "318 b'depthwise_conv2d_23/Bias_dequantize' 0  0 [48]\n",
      "319 b'depthwise_conv2d_29/Kernel_dequantize' 0  0 [1, 3, 3, 96]\n",
      "320   b'conv2d_15/Bias_dequantize' 0  0 [24]\n",
      "321 b'depthwise_conv2d_28/Bias_dequantize' 0  0 [96]\n",
      "322 b'depthwise_conv2d_10/Kernel_dequantize' 0  0 [1, 3, 3, 24]\n",
      "323 b'regressor_16/Kernel_dequantize' 0  0 [32, 1, 1, 96]\n",
      "324 b'conv2d_27/Kernel_dequantize' 0  0 [96, 1, 1, 96]\n",
      "325 b'depthwise_conv2d_9/Bias_dequantize' 0  0 [24]\n",
      "326   b'conv2d_26/Bias_dequantize' 0  0 [96]\n",
      "327    b'conv2d_8/Bias_dequantize' 0  0 [24]\n",
      "328 b'depthwise_conv2d_3/Kernel_dequantize' 0  0 [1, 3, 3, 24]\n",
      "329 b'conv2d_22/Kernel_dequantize' 0  0 [48, 1, 1, 48]\n",
      "330 b'depthwise_conv2d_11/Kernel_dequantize' 0  0 [1, 3, 3, 24]\n",
      "331 b'depthwise_conv2d_29/Bias_dequantize' 0  0 [96]\n",
      "332 b'depthwise_conv2d_2/Bias_dequantize' 0  0 [24]\n",
      "333 b'depthwise_conv2d_16/Kernel_dequantize' 0  0 [1, 3, 3, 48]\n",
      "334   b'conv2d_21/Bias_dequantize' 0  0 [48]\n",
      "335 b'depthwise_conv2d_30/Kernel_dequantize' 0  0 [1, 3, 3, 96]\n",
      "336 b'depthwise_conv2d_10/Bias_dequantize' 0  0 [24]\n",
      "337 b'regressor_16/Bias_dequantize' 0  0 [32]\n",
      "338 b'conv2d_16/Kernel_dequantize' 0  0 [48, 1, 1, 24]\n",
      "339 b'classificator_16/Kernel_dequantize' 0  0 [2, 1, 1, 96]\n",
      "340 b'conv2d_28/Kernel_dequantize' 0  0 [96, 1, 1, 96]\n",
      "341  b'conv2d_1/Kernel_dequantize' 0  0 [24, 1, 1, 24]\n",
      "342 b'depthwise_conv2d_17/Kernel_dequantize' 0  0 [1, 3, 3, 48]\n",
      "343 b'separable_conv2d__xeno_compat__depthwise/Kernel_dequantize' 0  0 [1, 3, 3, 96]\n",
      "344  b'conv2d_9/Kernel_dequantize' 0  0 [24, 1, 1, 24]\n",
      "345 b'depthwise_conv2d_4/Kernel_dequantize' 0  0 [1, 3, 3, 24]\n",
      "346   b'conv2d_27/Bias_dequantize' 0  0 [96]\n",
      "347    b'conv2d/Kernel_dequantize' 0  0 [24, 5, 5, 3]\n",
      "348 b'conv2d_23/Kernel_dequantize' 0  0 [48, 1, 1, 48]\n",
      "349 b'depthwise_conv2d_12/Kernel_dequantize' 0  0 [1, 3, 3, 24]\n",
      "350 b'depthwise_conv2d_16/Bias_dequantize' 0  0 [48]\n",
      "351 b'depthwise_conv2d_30/Bias_dequantize' 0  0 [96]\n",
      "352   b'conv2d_22/Bias_dequantize' 0  0 [48]\n",
      "353 b'depthwise_conv2d_3/Bias_dequantize' 0  0 [24]\n",
      "354  b'conv2d_2/Kernel_dequantize' 0  0 [24, 1, 1, 24]\n",
      "355   b'conv2d_16/Bias_dequantize' 0  0 [48]\n",
      "356 b'depthwise_conv2d_11/Bias_dequantize' 0  0 [24]\n",
      "357 b'depthwise_conv2d_5/Kernel_dequantize' 0  0 [1, 3, 3, 24]\n",
      "358    b'conv2d_1/Bias_dequantize' 0  0 [24]\n",
      "359 b'conv2d_29/Kernel_dequantize' 0  0 [96, 1, 1, 96]\n",
      "360    b'conv2d_9/Bias_dequantize' 0  0 [24]\n",
      "361 b'depthwise_conv2d_4/Bias_dequantize' 0  0 [24]\n",
      "362   b'conv2d_23/Bias_dequantize' 0  0 [48]\n",
      "363      b'conv2d/Bias_dequantize' 0  0 [24]\n",
      "364 b'depthwise_conv2d_18/Kernel_dequantize' 0  0 [1, 3, 3, 48]\n",
      "365   b'conv2d_28/Bias_dequantize' 0  0 [96]\n",
      "366 b'conv2d_10/Kernel_dequantize' 0  0 [24, 1, 1, 24]\n",
      "367 b'depthwise_conv2d_12/Bias_dequantize' 0  0 [24]\n",
      "368 b'classificator_16/Bias_dequantize' 0  0 [2]\n",
      "369 b'depthwise_conv2d_17/Bias_dequantize' 0  0 [48]\n",
      "370 b'separable_conv2d__xeno_compat__depthwise/Bias_dequantize' 0  0 [96]\n",
      "371 b'depthwise_conv2d_13/Kernel_dequantize' 0  0 [1, 3, 3, 24]\n",
      "372 b'conv2d_30/Kernel_dequantize' 0  0 [96, 1, 1, 96]\n",
      "373  b'conv2d_3/Kernel_dequantize' 0  0 [24, 1, 1, 24]\n",
      "374 b'regressor_32/Kernel_dequantize' 0  0 [96, 1, 1, 96]\n",
      "375 b'conv2d_11/Kernel_dequantize' 0  0 [24, 1, 1, 24]\n",
      "376   b'conv2d_29/Bias_dequantize' 0  0 [96]\n",
      "377 b'depthwise_conv2d_6/Kernel_dequantize' 0  0 [1, 3, 3, 24]\n",
      "378 b'depthwise_conv2d_24/Kernel_dequantize' 0  0 [1, 3, 3, 96]\n",
      "379    b'conv2d_2/Bias_dequantize' 0  0 [24]\n",
      "380 b'depthwise_conv2d_18/Bias_dequantize' 0  0 [48]\n",
      "381 b'depthwise_conv2d_14/Kernel_dequantize' 0  0 [1, 3, 3, 24]\n",
      "382   b'conv2d_10/Bias_dequantize' 0  0 [24]\n",
      "383 b'conv2d_24/Kernel_dequantize' 0  0 [96, 1, 1, 48]\n",
      "384 b'depthwise_conv2d_5/Bias_dequantize' 0  0 [24]\n",
      "385 b'depthwise_conv2d_19/Kernel_dequantize' 0  0 [1, 3, 3, 48]\n",
      "386  b'conv2d_4/Kernel_dequantize' 0  0 [24, 1, 1, 24]\n",
      "387 b'depthwise_conv2d_13/Bias_dequantize' 0  0 [24]\n",
      "388    b'conv2d_3/Bias_dequantize' 0  0 [24]\n",
      "389 b'conv2d_17/Kernel_dequantize' 0  0 [48, 1, 1, 48]\n",
      "390 b'conv2d_31/Kernel_dequantize' 0  0 [96, 1, 1, 96]\n",
      "391 b'depthwise_conv2d_6/Bias_dequantize' 0  0 [24]\n",
      "392 b'depthwise_conv2d_24/Bias_dequantize' 0  0 [96]\n",
      "393 b'depthwise_conv2d_20/Kernel_dequantize' 0  0 [1, 3, 3, 48]\n",
      "394 b'conv2d_12/Kernel_dequantize' 0  0 [24, 1, 1, 24]\n",
      "395 b'depthwise_conv2d_25/Kernel_dequantize' 0  0 [1, 3, 3, 96]\n",
      "396 b'depthwise_conv2d_7/Kernel_dequantize' 0  0 [1, 3, 3, 24]\n",
      "397   b'conv2d_30/Bias_dequantize' 0  0 [96]\n",
      "398 b'depthwise_conv2d_19/Bias_dequantize' 0  0 [48]\n",
      "399   b'conv2d_24/Bias_dequantize' 0  0 [96]\n",
      "400 b'regressor_32/Bias_dequantize' 0  0 [96]\n",
      "401 b'depthwise_conv2d_15/Kernel_dequantize' 0  0 [1, 3, 3, 24]\n",
      "402   b'conv2d_11/Bias_dequantize' 0  0 [24]\n",
      "403 b'separable_conv2d/Kernel_dequantize' 0  0 [96, 1, 1, 96]\n",
      "404  b'conv2d_5/Kernel_dequantize' 0  0 [24, 1, 1, 24]\n",
      "405 b'depthwise_conv2d_14/Bias_dequantize' 0  0 [24]\n",
      "406 b'classificator_32/Kernel_dequantize' 0  0 [6, 1, 1, 96]\n",
      "407   b'conv2d_31/Bias_dequantize' 0  0 [96]\n",
      "408 b'conv2d_13/Kernel_dequantize' 0  0 [24, 1, 1, 24]\n",
      "409 b'depthwise_conv2d_26/Kernel_dequantize' 0  0 [1, 3, 3, 96]\n",
      "410    b'conv2d_4/Bias_dequantize' 0  0 [24]\n",
      "411 b'conv2d_18/Kernel_dequantize' 0  0 [48, 1, 1, 48]\n",
      "412   b'conv2d_12/Bias_dequantize' 0  0 [24]\n",
      "413 b'depthwise_conv2d_7/Bias_dequantize' 0  0 [24]\n",
      "414 b'depthwise_conv2d_21/Kernel_dequantize' 0  0 [1, 3, 3, 48]\n",
      "415 b'depthwise_conv2d_25/Bias_dequantize' 0  0 [96]\n",
      "416   b'conv2d_17/Bias_dequantize' 0  0 [48]\n",
      "417 b'depthwise_conv2d_15/Bias_dequantize' 0  0 [24]\n",
      "418 b'depthwise_conv2d_20/Bias_dequantize' 0  0 [48]\n",
      "419 b'conv2d_19/Kernel_dequantize' 0  0 [48, 1, 1, 48]\n",
      "420 b'depthwise_conv2d/Kernel_dequantize' 0  0 [1, 3, 3, 24]\n",
      "421 b'classificator_32/Bias_dequantize' 0  0 [6]\n",
      "422  b'conv2d_6/Kernel_dequantize' 0  0 [24, 1, 1, 24]\n"
     ]
    }
   ],
   "source": [
    "print_graph(back_subgraph)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "back_tensor_dict = {(back_subgraph.Tensors(i).Name().decode(\"utf8\")): i \n",
    "               for i in range(back_subgraph.TensorsLength())}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "140"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "back_parameters = get_parameters(back_subgraph)\n",
    "len(back_parameters)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((24, 5, 5, 3), (24,))"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "W = get_weights(back_model, back_subgraph, back_tensor_dict, \"conv2d/Kernel\")\n",
    "b = get_weights(back_model, back_subgraph, back_tensor_dict, \"conv2d/Bias\")\n",
    "W.shape, b.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "back_net = BlazeFace(back_model=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "BlazeFace(\n",
       "  (backbone): Sequential(\n",
       "    (0): Conv2d(3, 24, kernel_size=(5, 5), stride=(2, 2))\n",
       "    (1): ReLU(inplace=True)\n",
       "    (2): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(24, 24, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=24)\n",
       "        (1): Conv2d(24, 24, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (3): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(24, 24, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=24)\n",
       "        (1): Conv2d(24, 24, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (4): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(24, 24, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=24)\n",
       "        (1): Conv2d(24, 24, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (5): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(24, 24, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=24)\n",
       "        (1): Conv2d(24, 24, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (6): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(24, 24, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=24)\n",
       "        (1): Conv2d(24, 24, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (7): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(24, 24, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=24)\n",
       "        (1): Conv2d(24, 24, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (8): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(24, 24, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=24)\n",
       "        (1): Conv2d(24, 24, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (9): BlazeBlock(\n",
       "      (max_pool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(24, 24, kernel_size=(3, 3), stride=(2, 2), groups=24)\n",
       "        (1): Conv2d(24, 24, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (10): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(24, 24, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=24)\n",
       "        (1): Conv2d(24, 24, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (11): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(24, 24, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=24)\n",
       "        (1): Conv2d(24, 24, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (12): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(24, 24, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=24)\n",
       "        (1): Conv2d(24, 24, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (13): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(24, 24, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=24)\n",
       "        (1): Conv2d(24, 24, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (14): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(24, 24, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=24)\n",
       "        (1): Conv2d(24, 24, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (15): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(24, 24, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=24)\n",
       "        (1): Conv2d(24, 24, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (16): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(24, 24, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=24)\n",
       "        (1): Conv2d(24, 24, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (17): BlazeBlock(\n",
       "      (max_pool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(24, 24, kernel_size=(3, 3), stride=(2, 2), groups=24)\n",
       "        (1): Conv2d(24, 48, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (18): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(48, 48, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=48)\n",
       "        (1): Conv2d(48, 48, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (19): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(48, 48, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=48)\n",
       "        (1): Conv2d(48, 48, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (20): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(48, 48, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=48)\n",
       "        (1): Conv2d(48, 48, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (21): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(48, 48, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=48)\n",
       "        (1): Conv2d(48, 48, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (22): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(48, 48, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=48)\n",
       "        (1): Conv2d(48, 48, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (23): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(48, 48, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=48)\n",
       "        (1): Conv2d(48, 48, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (24): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(48, 48, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=48)\n",
       "        (1): Conv2d(48, 48, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (25): BlazeBlock(\n",
       "      (max_pool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(48, 48, kernel_size=(3, 3), stride=(2, 2), groups=48)\n",
       "        (1): Conv2d(48, 96, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (26): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(96, 96, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=96)\n",
       "        (1): Conv2d(96, 96, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (27): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(96, 96, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=96)\n",
       "        (1): Conv2d(96, 96, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (28): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(96, 96, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=96)\n",
       "        (1): Conv2d(96, 96, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (29): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(96, 96, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=96)\n",
       "        (1): Conv2d(96, 96, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (30): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(96, 96, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=96)\n",
       "        (1): Conv2d(96, 96, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (31): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(96, 96, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=96)\n",
       "        (1): Conv2d(96, 96, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "    (32): BlazeBlock(\n",
       "      (convs): Sequential(\n",
       "        (0): Conv2d(96, 96, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=96)\n",
       "        (1): Conv2d(96, 96, kernel_size=(1, 1), stride=(1, 1))\n",
       "      )\n",
       "      (act): ReLU(inplace=True)\n",
       "    )\n",
       "  )\n",
       "  (final): FinalBlazeBlock(\n",
       "    (convs): Sequential(\n",
       "      (0): Conv2d(96, 96, kernel_size=(3, 3), stride=(2, 2), groups=96)\n",
       "      (1): Conv2d(96, 96, kernel_size=(1, 1), stride=(1, 1))\n",
       "    )\n",
       "    (act): ReLU(inplace=True)\n",
       "  )\n",
       "  (classifier_8): Conv2d(96, 2, kernel_size=(1, 1), stride=(1, 1))\n",
       "  (classifier_16): Conv2d(96, 6, kernel_size=(1, 1), stride=(1, 1))\n",
       "  (regressor_8): Conv2d(96, 32, kernel_size=(1, 1), stride=(1, 1))\n",
       "  (regressor_16): Conv2d(96, 96, kernel_size=(1, 1), stride=(1, 1))\n",
       ")"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "back_net"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['conv2d/Kernel',\n",
       " 'conv2d/Bias',\n",
       " 'depthwise_conv2d/Kernel',\n",
       " 'depthwise_conv2d/Bias',\n",
       " 'conv2d_1/Kernel']"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "back_probable_names = get_probable_names(back_subgraph)\n",
    "back_probable_names[:5]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "back_convert = get_convert(back_net, back_probable_names)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "backbone.0.weight conv2d/Kernel (24, 5, 5, 3) torch.Size([24, 3, 5, 5])\n",
      "backbone.0.bias conv2d/Bias (24,) torch.Size([24])\n",
      "backbone.2.convs.0.weight depthwise_conv2d/Kernel (1, 3, 3, 24) torch.Size([24, 1, 3, 3])\n",
      "backbone.2.convs.0.bias depthwise_conv2d/Bias (24,) torch.Size([24])\n",
      "backbone.2.convs.1.weight conv2d_1/Kernel (24, 1, 1, 24) torch.Size([24, 24, 1, 1])\n",
      "backbone.2.convs.1.bias conv2d_1/Bias (24,) torch.Size([24])\n",
      "backbone.3.convs.0.weight depthwise_conv2d_1/Kernel (1, 3, 3, 24) torch.Size([24, 1, 3, 3])\n",
      "backbone.3.convs.0.bias depthwise_conv2d_1/Bias (24,) torch.Size([24])\n",
      "backbone.3.convs.1.weight conv2d_2/Kernel (24, 1, 1, 24) torch.Size([24, 24, 1, 1])\n",
      "backbone.3.convs.1.bias conv2d_2/Bias (24,) torch.Size([24])\n",
      "backbone.4.convs.0.weight depthwise_conv2d_2/Kernel (1, 3, 3, 24) torch.Size([24, 1, 3, 3])\n",
      "backbone.4.convs.0.bias depthwise_conv2d_2/Bias (24,) torch.Size([24])\n",
      "backbone.4.convs.1.weight conv2d_3/Kernel (24, 1, 1, 24) torch.Size([24, 24, 1, 1])\n",
      "backbone.4.convs.1.bias conv2d_3/Bias (24,) torch.Size([24])\n",
      "backbone.5.convs.0.weight depthwise_conv2d_3/Kernel (1, 3, 3, 24) torch.Size([24, 1, 3, 3])\n",
      "backbone.5.convs.0.bias depthwise_conv2d_3/Bias (24,) torch.Size([24])\n",
      "backbone.5.convs.1.weight conv2d_4/Kernel (24, 1, 1, 24) torch.Size([24, 24, 1, 1])\n",
      "backbone.5.convs.1.bias conv2d_4/Bias (24,) torch.Size([24])\n",
      "backbone.6.convs.0.weight depthwise_conv2d_4/Kernel (1, 3, 3, 24) torch.Size([24, 1, 3, 3])\n",
      "backbone.6.convs.0.bias depthwise_conv2d_4/Bias (24,) torch.Size([24])\n",
      "backbone.6.convs.1.weight conv2d_5/Kernel (24, 1, 1, 24) torch.Size([24, 24, 1, 1])\n",
      "backbone.6.convs.1.bias conv2d_5/Bias (24,) torch.Size([24])\n",
      "backbone.7.convs.0.weight depthwise_conv2d_5/Kernel (1, 3, 3, 24) torch.Size([24, 1, 3, 3])\n",
      "backbone.7.convs.0.bias depthwise_conv2d_5/Bias (24,) torch.Size([24])\n",
      "backbone.7.convs.1.weight conv2d_6/Kernel (24, 1, 1, 24) torch.Size([24, 24, 1, 1])\n",
      "backbone.7.convs.1.bias conv2d_6/Bias (24,) torch.Size([24])\n",
      "backbone.8.convs.0.weight depthwise_conv2d_6/Kernel (1, 3, 3, 24) torch.Size([24, 1, 3, 3])\n",
      "backbone.8.convs.0.bias depthwise_conv2d_6/Bias (24,) torch.Size([24])\n",
      "backbone.8.convs.1.weight conv2d_7/Kernel (24, 1, 1, 24) torch.Size([24, 24, 1, 1])\n",
      "backbone.8.convs.1.bias conv2d_7/Bias (24,) torch.Size([24])\n",
      "backbone.9.convs.0.weight depthwise_conv2d_7/Kernel (1, 3, 3, 24) torch.Size([24, 1, 3, 3])\n",
      "backbone.9.convs.0.bias depthwise_conv2d_7/Bias (24,) torch.Size([24])\n",
      "backbone.9.convs.1.weight conv2d_8/Kernel (24, 1, 1, 24) torch.Size([24, 24, 1, 1])\n",
      "backbone.9.convs.1.bias conv2d_8/Bias (24,) torch.Size([24])\n",
      "backbone.10.convs.0.weight depthwise_conv2d_8/Kernel (1, 3, 3, 24) torch.Size([24, 1, 3, 3])\n",
      "backbone.10.convs.0.bias depthwise_conv2d_8/Bias (24,) torch.Size([24])\n",
      "backbone.10.convs.1.weight conv2d_9/Kernel (24, 1, 1, 24) torch.Size([24, 24, 1, 1])\n",
      "backbone.10.convs.1.bias conv2d_9/Bias (24,) torch.Size([24])\n",
      "backbone.11.convs.0.weight depthwise_conv2d_9/Kernel (1, 3, 3, 24) torch.Size([24, 1, 3, 3])\n",
      "backbone.11.convs.0.bias depthwise_conv2d_9/Bias (24,) torch.Size([24])\n",
      "backbone.11.convs.1.weight conv2d_10/Kernel (24, 1, 1, 24) torch.Size([24, 24, 1, 1])\n",
      "backbone.11.convs.1.bias conv2d_10/Bias (24,) torch.Size([24])\n",
      "backbone.12.convs.0.weight depthwise_conv2d_10/Kernel (1, 3, 3, 24) torch.Size([24, 1, 3, 3])\n",
      "backbone.12.convs.0.bias depthwise_conv2d_10/Bias (24,) torch.Size([24])\n",
      "backbone.12.convs.1.weight conv2d_11/Kernel (24, 1, 1, 24) torch.Size([24, 24, 1, 1])\n",
      "backbone.12.convs.1.bias conv2d_11/Bias (24,) torch.Size([24])\n",
      "backbone.13.convs.0.weight depthwise_conv2d_11/Kernel (1, 3, 3, 24) torch.Size([24, 1, 3, 3])\n",
      "backbone.13.convs.0.bias depthwise_conv2d_11/Bias (24,) torch.Size([24])\n",
      "backbone.13.convs.1.weight conv2d_12/Kernel (24, 1, 1, 24) torch.Size([24, 24, 1, 1])\n",
      "backbone.13.convs.1.bias conv2d_12/Bias (24,) torch.Size([24])\n",
      "backbone.14.convs.0.weight depthwise_conv2d_12/Kernel (1, 3, 3, 24) torch.Size([24, 1, 3, 3])\n",
      "backbone.14.convs.0.bias depthwise_conv2d_12/Bias (24,) torch.Size([24])\n",
      "backbone.14.convs.1.weight conv2d_13/Kernel (24, 1, 1, 24) torch.Size([24, 24, 1, 1])\n",
      "backbone.14.convs.1.bias conv2d_13/Bias (24,) torch.Size([24])\n",
      "backbone.15.convs.0.weight depthwise_conv2d_13/Kernel (1, 3, 3, 24) torch.Size([24, 1, 3, 3])\n",
      "backbone.15.convs.0.bias depthwise_conv2d_13/Bias (24,) torch.Size([24])\n",
      "backbone.15.convs.1.weight conv2d_14/Kernel (24, 1, 1, 24) torch.Size([24, 24, 1, 1])\n",
      "backbone.15.convs.1.bias conv2d_14/Bias (24,) torch.Size([24])\n",
      "backbone.16.convs.0.weight depthwise_conv2d_14/Kernel (1, 3, 3, 24) torch.Size([24, 1, 3, 3])\n",
      "backbone.16.convs.0.bias depthwise_conv2d_14/Bias (24,) torch.Size([24])\n",
      "backbone.16.convs.1.weight conv2d_15/Kernel (24, 1, 1, 24) torch.Size([24, 24, 1, 1])\n",
      "backbone.16.convs.1.bias conv2d_15/Bias (24,) torch.Size([24])\n",
      "backbone.17.convs.0.weight depthwise_conv2d_15/Kernel (1, 3, 3, 24) torch.Size([24, 1, 3, 3])\n",
      "backbone.17.convs.0.bias depthwise_conv2d_15/Bias (24,) torch.Size([24])\n",
      "backbone.17.convs.1.weight conv2d_16/Kernel (48, 1, 1, 24) torch.Size([48, 24, 1, 1])\n",
      "backbone.17.convs.1.bias conv2d_16/Bias (48,) torch.Size([48])\n",
      "backbone.18.convs.0.weight depthwise_conv2d_16/Kernel (1, 3, 3, 48) torch.Size([48, 1, 3, 3])\n",
      "backbone.18.convs.0.bias depthwise_conv2d_16/Bias (48,) torch.Size([48])\n",
      "backbone.18.convs.1.weight conv2d_17/Kernel (48, 1, 1, 48) torch.Size([48, 48, 1, 1])\n",
      "backbone.18.convs.1.bias conv2d_17/Bias (48,) torch.Size([48])\n",
      "backbone.19.convs.0.weight depthwise_conv2d_17/Kernel (1, 3, 3, 48) torch.Size([48, 1, 3, 3])\n",
      "backbone.19.convs.0.bias depthwise_conv2d_17/Bias (48,) torch.Size([48])\n",
      "backbone.19.convs.1.weight conv2d_18/Kernel (48, 1, 1, 48) torch.Size([48, 48, 1, 1])\n",
      "backbone.19.convs.1.bias conv2d_18/Bias (48,) torch.Size([48])\n",
      "backbone.20.convs.0.weight depthwise_conv2d_18/Kernel (1, 3, 3, 48) torch.Size([48, 1, 3, 3])\n",
      "backbone.20.convs.0.bias depthwise_conv2d_18/Bias (48,) torch.Size([48])\n",
      "backbone.20.convs.1.weight conv2d_19/Kernel (48, 1, 1, 48) torch.Size([48, 48, 1, 1])\n",
      "backbone.20.convs.1.bias conv2d_19/Bias (48,) torch.Size([48])\n",
      "backbone.21.convs.0.weight depthwise_conv2d_19/Kernel (1, 3, 3, 48) torch.Size([48, 1, 3, 3])\n",
      "backbone.21.convs.0.bias depthwise_conv2d_19/Bias (48,) torch.Size([48])\n",
      "backbone.21.convs.1.weight conv2d_20/Kernel (48, 1, 1, 48) torch.Size([48, 48, 1, 1])\n",
      "backbone.21.convs.1.bias conv2d_20/Bias (48,) torch.Size([48])\n",
      "backbone.22.convs.0.weight depthwise_conv2d_20/Kernel (1, 3, 3, 48) torch.Size([48, 1, 3, 3])\n",
      "backbone.22.convs.0.bias depthwise_conv2d_20/Bias (48,) torch.Size([48])\n",
      "backbone.22.convs.1.weight conv2d_21/Kernel (48, 1, 1, 48) torch.Size([48, 48, 1, 1])\n",
      "backbone.22.convs.1.bias conv2d_21/Bias (48,) torch.Size([48])\n",
      "backbone.23.convs.0.weight depthwise_conv2d_21/Kernel (1, 3, 3, 48) torch.Size([48, 1, 3, 3])\n",
      "backbone.23.convs.0.bias depthwise_conv2d_21/Bias (48,) torch.Size([48])\n",
      "backbone.23.convs.1.weight conv2d_22/Kernel (48, 1, 1, 48) torch.Size([48, 48, 1, 1])\n",
      "backbone.23.convs.1.bias conv2d_22/Bias (48,) torch.Size([48])\n",
      "backbone.24.convs.0.weight depthwise_conv2d_22/Kernel (1, 3, 3, 48) torch.Size([48, 1, 3, 3])\n",
      "backbone.24.convs.0.bias depthwise_conv2d_22/Bias (48,) torch.Size([48])\n",
      "backbone.24.convs.1.weight conv2d_23/Kernel (48, 1, 1, 48) torch.Size([48, 48, 1, 1])\n",
      "backbone.24.convs.1.bias conv2d_23/Bias (48,) torch.Size([48])\n",
      "backbone.25.convs.0.weight depthwise_conv2d_23/Kernel (1, 3, 3, 48) torch.Size([48, 1, 3, 3])\n",
      "backbone.25.convs.0.bias depthwise_conv2d_23/Bias (48,) torch.Size([48])\n",
      "backbone.25.convs.1.weight conv2d_24/Kernel (96, 1, 1, 48) torch.Size([96, 48, 1, 1])\n",
      "backbone.25.convs.1.bias conv2d_24/Bias (96,) torch.Size([96])\n",
      "backbone.26.convs.0.weight depthwise_conv2d_24/Kernel (1, 3, 3, 96) torch.Size([96, 1, 3, 3])\n",
      "backbone.26.convs.0.bias depthwise_conv2d_24/Bias (96,) torch.Size([96])\n",
      "backbone.26.convs.1.weight conv2d_25/Kernel (96, 1, 1, 96) torch.Size([96, 96, 1, 1])\n",
      "backbone.26.convs.1.bias conv2d_25/Bias (96,) torch.Size([96])\n",
      "backbone.27.convs.0.weight depthwise_conv2d_25/Kernel (1, 3, 3, 96) torch.Size([96, 1, 3, 3])\n",
      "backbone.27.convs.0.bias depthwise_conv2d_25/Bias (96,) torch.Size([96])\n",
      "backbone.27.convs.1.weight conv2d_26/Kernel (96, 1, 1, 96) torch.Size([96, 96, 1, 1])\n",
      "backbone.27.convs.1.bias conv2d_26/Bias (96,) torch.Size([96])\n",
      "backbone.28.convs.0.weight depthwise_conv2d_26/Kernel (1, 3, 3, 96) torch.Size([96, 1, 3, 3])\n",
      "backbone.28.convs.0.bias depthwise_conv2d_26/Bias (96,) torch.Size([96])\n",
      "backbone.28.convs.1.weight conv2d_27/Kernel (96, 1, 1, 96) torch.Size([96, 96, 1, 1])\n",
      "backbone.28.convs.1.bias conv2d_27/Bias (96,) torch.Size([96])\n",
      "backbone.29.convs.0.weight depthwise_conv2d_27/Kernel (1, 3, 3, 96) torch.Size([96, 1, 3, 3])\n",
      "backbone.29.convs.0.bias depthwise_conv2d_27/Bias (96,) torch.Size([96])\n",
      "backbone.29.convs.1.weight conv2d_28/Kernel (96, 1, 1, 96) torch.Size([96, 96, 1, 1])\n",
      "backbone.29.convs.1.bias conv2d_28/Bias (96,) torch.Size([96])\n",
      "backbone.30.convs.0.weight depthwise_conv2d_28/Kernel (1, 3, 3, 96) torch.Size([96, 1, 3, 3])\n",
      "backbone.30.convs.0.bias depthwise_conv2d_28/Bias (96,) torch.Size([96])\n",
      "backbone.30.convs.1.weight conv2d_29/Kernel (96, 1, 1, 96) torch.Size([96, 96, 1, 1])\n",
      "backbone.30.convs.1.bias conv2d_29/Bias (96,) torch.Size([96])\n",
      "backbone.31.convs.0.weight depthwise_conv2d_29/Kernel (1, 3, 3, 96) torch.Size([96, 1, 3, 3])\n",
      "backbone.31.convs.0.bias depthwise_conv2d_29/Bias (96,) torch.Size([96])\n",
      "backbone.31.convs.1.weight conv2d_30/Kernel (96, 1, 1, 96) torch.Size([96, 96, 1, 1])\n",
      "backbone.31.convs.1.bias conv2d_30/Bias (96,) torch.Size([96])\n",
      "backbone.32.convs.0.weight depthwise_conv2d_30/Kernel (1, 3, 3, 96) torch.Size([96, 1, 3, 3])\n",
      "backbone.32.convs.0.bias depthwise_conv2d_30/Bias (96,) torch.Size([96])\n",
      "backbone.32.convs.1.weight conv2d_31/Kernel (96, 1, 1, 96) torch.Size([96, 96, 1, 1])\n",
      "backbone.32.convs.1.bias conv2d_31/Bias (96,) torch.Size([96])\n",
      "final.convs.0.weight separable_conv2d__xeno_compat__depthwise/Kernel (1, 3, 3, 96) torch.Size([96, 1, 3, 3])\n",
      "final.convs.0.bias separable_conv2d__xeno_compat__depthwise/Bias (96,) torch.Size([96])\n",
      "final.convs.1.weight separable_conv2d/Kernel (96, 1, 1, 96) torch.Size([96, 96, 1, 1])\n",
      "final.convs.1.bias separable_conv2d/Bias (96,) torch.Size([96])\n",
      "classifier_8.weight classificator_16/Kernel (2, 1, 1, 96) torch.Size([2, 96, 1, 1])\n",
      "classifier_8.bias classificator_16/Bias (2,) torch.Size([2])\n",
      "classifier_16.weight classificator_32/Kernel (6, 1, 1, 96) torch.Size([6, 96, 1, 1])\n",
      "classifier_16.bias classificator_32/Bias (6,) torch.Size([6])\n",
      "regressor_8.weight regressor_16/Kernel (32, 1, 1, 96) torch.Size([32, 96, 1, 1])\n",
      "regressor_8.bias regressor_16/Bias (32,) torch.Size([32])\n",
      "regressor_16.weight regressor_32/Kernel (96, 1, 1, 96) torch.Size([96, 96, 1, 1])\n",
      "regressor_16.bias regressor_32/Bias (96,) torch.Size([96])\n"
     ]
    }
   ],
   "source": [
    "back_state_dict = build_state_dict(back_model, back_subgraph, back_tensor_dict, back_net, back_convert)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<All keys matched successfully>"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "back_net.load_state_dict(back_state_dict, strict=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "torch.save(back_net.state_dict(), \"blazefaceback.pth\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
